From 3868a0020611491e30db19e5b27d33a7559c7071 Mon Sep 17 00:00:00 2001
From: Andrey Sukharev <SukharevAndrey@users.noreply.github.com>
Date: Sun, 4 Dec 2022 03:43:23 +0300
Subject: [PATCH] Use source generated regular expressions (#4005)

---
 Ryujinx.Graphics.Vulkan/Vendor.cs             |  5 +--
 Ryujinx.Graphics.Vulkan/VulkanRenderer.cs     |  2 +-
 Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs  |  7 ++--
 .../Sockets/Sfdnsres/Proxy/DnsBlacklist.cs    | 32 +++++++++++++------
 .../Loaders/Executables/NsoExecutable.cs      | 15 ++++++---
 5 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/Ryujinx.Graphics.Vulkan/Vendor.cs b/Ryujinx.Graphics.Vulkan/Vendor.cs
index f06211ca..7a6e0e60 100644
--- a/Ryujinx.Graphics.Vulkan/Vendor.cs
+++ b/Ryujinx.Graphics.Vulkan/Vendor.cs
@@ -11,9 +11,10 @@ namespace Ryujinx.Graphics.Vulkan
         Unknown
     }
 
-    static class VendorUtils
+    static partial class VendorUtils
     {
-        public static Regex AmdGcnRegex = new Regex(@"Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\d{2}(\D|$))|([7-8]\d{3}(\D|$))|Fury|Nano))|(Pro Duo)");
+        [GeneratedRegex("Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")]
+        public static partial Regex AmdGcnRegex();
 
         public static Vendor FromId(uint id)
         {
diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index f711ac9c..5370335d 100644
--- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -471,7 +471,7 @@ namespace Ryujinx.Graphics.Vulkan
             GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)properties.DeviceName);
             GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}";
 
-            IsAmdGcn = Vendor == Vendor.Amd && VendorUtils.AmdGcnRegex.IsMatch(GpuRenderer);
+            IsAmdGcn = Vendor == Vendor.Amd && VendorUtils.AmdGcnRegex().IsMatch(GpuRenderer);
 
             Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
         }
diff --git a/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
index 0ca90130..bd321f6f 100644
--- a/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
+++ b/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
@@ -18,7 +18,7 @@ using System.Text.RegularExpressions;
 
 namespace Ryujinx.HLE.HOS.Applets.Error
 {
-    internal class ErrorApplet : IApplet
+    internal partial class ErrorApplet : IApplet
     {
         private const long ErrorMessageBinaryTitleId = 0x0100000000000801;
 
@@ -30,6 +30,9 @@ namespace Ryujinx.HLE.HOS.Applets.Error
 
         public event EventHandler AppletStateChanged;
 
+        [GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")]
+        private static partial Regex CleanTextRegex();
+
         public ErrorApplet(Horizon horizon)
         {
             _horizon = horizon;
@@ -101,7 +104,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error
 
         private static string CleanText(string value)
         {
-            return Regex.Replace(value, @"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..", "").Replace("\0", "");
+            return CleanTextRegex().Replace(value, "").Replace("\0", "");
         }
 
         private string GetMessageText(uint module, uint description, string key)
diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs
index ddfe232c..776a6f7c 100644
--- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs
+++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs
@@ -2,18 +2,30 @@
 
 namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy
 {
-    static class DnsBlacklist
+    static partial class DnsBlacklist
     {
-        const RegexOptions RegexOpts = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled;
+        const RegexOptions RegexOpts = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
 
-        private static readonly Regex[] BlockedHosts = new Regex[]
-        {
-            new Regex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", RegexOpts),
-            new Regex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", RegexOpts),
-            new Regex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", RegexOpts),
-            new Regex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", RegexOpts),
-            new Regex(@"^(.*)\-sb\.accounts\.nintendo\.com$", RegexOpts),
-            new Regex(@"^accounts\.nintendo\.com$", RegexOpts)
+        [GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", RegexOpts)]
+        private static partial Regex BlockedHost1();
+        [GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", RegexOpts)]
+        private static partial Regex BlockedHost2();
+        [GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", RegexOpts)]
+        private static partial Regex BlockedHost3();
+        [GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", RegexOpts)]
+        private static partial Regex BlockedHost4();
+        [GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", RegexOpts)]
+        private static partial Regex BlockedHost5();
+        [GeneratedRegex(@"^accounts\.nintendo\.com$", RegexOpts)]
+        private static partial Regex BlockedHost6();
+
+        private static readonly Regex[] BlockedHosts = {
+            BlockedHost1(),
+            BlockedHost2(),
+            BlockedHost3(),
+            BlockedHost4(),
+            BlockedHost5(),
+            BlockedHost6()
         };
 
         public static bool IsHostBlocked(string host)
diff --git a/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs b/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs
index d3c0d1bf..d695449b 100644
--- a/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs
+++ b/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs
@@ -9,7 +9,7 @@ using System.Text.RegularExpressions;
 
 namespace Ryujinx.HLE.Loaders.Executables
 {
-    class NsoExecutable : IExecutable
+    partial class NsoExecutable : IExecutable
     {
         public byte[] Program { get; }
         public Span<byte> Text => Program.AsSpan((int)TextOffset, (int)TextSize);
@@ -29,6 +29,13 @@ namespace Ryujinx.HLE.Loaders.Executables
         public string        Name;
         public Array32<byte> BuildId;
 
+        [GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
+        private static partial Regex ModuleRegex();
+        [GeneratedRegex(@"sdk_version: ([0-9.]*)")]
+        private static partial Regex FsSdkRegex();
+        [GeneratedRegex(@"SDK MW[ -~]*")]
+        private static partial Regex SdkMwRegex();
+
         public NsoExecutable(IStorage inStorage, string name = null)
         {
             NsoReader reader = new NsoReader();
@@ -83,7 +90,7 @@ namespace Ryujinx.HLE.Loaders.Executables
 
             if (string.IsNullOrEmpty(modulePath))
             {
-                Match moduleMatch = Regex.Match(rawTextBuffer, @"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled);
+                Match moduleMatch = ModuleRegex().Match(rawTextBuffer);
                 if (moduleMatch.Success)
                 {
                     modulePath = moduleMatch.Value;
@@ -92,13 +99,13 @@ namespace Ryujinx.HLE.Loaders.Executables
 
             stringBuilder.AppendLine($"    Module: {modulePath}");
 
-            Match fsSdkMatch = Regex.Match(rawTextBuffer, @"sdk_version: ([0-9.]*)", RegexOptions.Compiled);
+            Match fsSdkMatch = FsSdkRegex().Match(rawTextBuffer);
             if (fsSdkMatch.Success)
             {
                 stringBuilder.AppendLine($"    FS SDK Version: {fsSdkMatch.Value.Replace("sdk_version: ", "")}");
             }
 
-            MatchCollection sdkMwMatches = Regex.Matches(rawTextBuffer, @"SDK MW[ -~]*", RegexOptions.Compiled);
+            MatchCollection sdkMwMatches = SdkMwRegex().Matches(rawTextBuffer);
             if (sdkMwMatches.Count != 0)
             {
                 string libHeader  = "    SDK Libraries: ";