From 96b6f475a3b2a200ae02137f2aa8ab6fd949971c Mon Sep 17 00:00:00 2001
From: Stossy11 <69031796+stossy11@users.noreply.github.com>
Date: Tue, 3 Dec 2024 20:33:09 +1100
Subject: [PATCH] Fix Alignment

---
 src/MeloNX/MeloNX.xcodeproj/project.pbxproj   |  2 ++
 .../Utilities/EmbeddedResources.cs            |  4 ++-
 .../LightningJit/Cache/JitCache.cs            | 29 ++++++++++++++---
 .../LightningJit/Cache/JitSupportDarwin.cs    | 31 +++++++++++++++++++
 src/Ryujinx/Common/LocaleManager.cs           |  3 ++
 5 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
index b59f3c972..9c95d1966 100644
--- a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
+++ b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
@@ -578,6 +578,7 @@
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 				);
 				MARKETING_VERSION = 1.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
@@ -692,6 +693,7 @@
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 				);
 				MARKETING_VERSION = 1.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
diff --git a/src/Ryujinx.Common/Utilities/EmbeddedResources.cs b/src/Ryujinx.Common/Utilities/EmbeddedResources.cs
index b4b6e6beb..d7990ad58 100644
--- a/src/Ryujinx.Common/Utilities/EmbeddedResources.cs
+++ b/src/Ryujinx.Common/Utilities/EmbeddedResources.cs
@@ -135,11 +135,13 @@ namespace Ryujinx.Common
         private static (Assembly, string) ResolveManifestPath(string filename)
         {
             CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
+            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
+            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
             var segments = filename.Split('/', 2, StringSplitOptions.RemoveEmptyEntries);
 
             if (segments.Length >= 2)
             {
-                foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
+                foreach (var assembly in System.Runtime.Loader.AssemblyLoadContext.Default.Assemblies)
                 {
                     if (assembly.GetName().Name == segments[0])
                     {
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs
index ac1274bf6..c8a90e3b3 100644
--- a/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitCache.cs
@@ -15,7 +15,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
 
         private const int CodeAlignment = 4; // Bytes.
         private const int CacheSize = 2047 * 1024 * 1024;
-
+        private const int CacheSizeIOS = 512 * 1024 * 1024;
         private static ReservedRegion _jitRegion;
         private static JitCacheInvalidation _jitCacheInvalidator;
 
@@ -44,9 +44,9 @@ namespace Ryujinx.Cpu.LightningJit.Cache
                     return;
                 }
 
-                _jitRegion = new ReservedRegion(allocator, CacheSize);
+                _jitRegion = new ReservedRegion(allocator, (ulong)(OperatingSystem.IsIOS() ? CacheSizeIOS : CacheSize));
 
-                if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS())
+                if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS() && !OperatingSystem.IsIOS())
                 {
                     _jitCacheInvalidator = new JitCacheInvalidation(allocator);
                 }
@@ -67,7 +67,14 @@ namespace Ryujinx.Cpu.LightningJit.Cache
 
                 nint funcPtr = _jitRegion.Pointer + funcOffset;
 
-                if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
+                if (OperatingSystem.IsIOS())
+                {
+                    code.CopyTo(new Span<byte>((void*)funcPtr, code.Length));
+                    ReprotectAsExecutable(funcOffset, code.Length);
+
+                    JitSupportDarwinAot.Invalidate(funcPtr, (ulong)code.Length);
+                }
+                else if (OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
                 {
                     unsafe
                     {
@@ -101,6 +108,11 @@ namespace Ryujinx.Cpu.LightningJit.Cache
 
         public static void Unmap(nint pointer)
         {
+            if (OperatingSystem.IsIOS())
+            {
+                return;
+            }
+
             lock (_lock)
             {
                 Debug.Assert(_initialized);
@@ -153,7 +165,14 @@ namespace Ryujinx.Cpu.LightningJit.Cache
 
         private static int AlignCodeSize(int codeSize)
         {
-            return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
+            int alignment = CodeAlignment;
+
+            if (OperatingSystem.IsIOS())
+            {
+                alignment = 0x4000;
+            }
+
+            return checked(codeSize + (alignment - 1)) & ~(alignment - 1);
         }
 
         private static void Add(int offset, int size)
diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs
index ed02a9c28..6e064b16f 100644
--- a/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs
+++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs
@@ -13,4 +13,35 @@ namespace Ryujinx.Cpu.LightningJit.Cache
         [LibraryImport("libc", EntryPoint = "sys_icache_invalidate", SetLastError = true)]
         public static partial void SysIcacheInvalidate(nint start, nint len);
     }
+    
+    [SupportedOSPlatform("ios")]
+    internal static partial class JitSupportDarwinAot
+    {
+        [LibraryImport("pthread", EntryPoint = "pthread_jit_write_protect_np")]
+        private static partial void pthread_jit_write_protect_np(int enabled);
+
+        [LibraryImport("libc", EntryPoint = "sys_icache_invalidate")]
+        private static partial void sys_icache_invalidate(IntPtr start, IntPtr length);
+
+        public static unsafe void Copy(IntPtr dst, IntPtr src, ulong n) {
+            // When NativeAOT is in use, we can toggle per-thread write protection without worrying about breaking .NET code.
+
+            //pthread_jit_write_protect_np(0);
+            
+            var srcSpan = new Span<byte>(src.ToPointer(), (int)n);
+            var dstSpan = new Span<byte>(dst.ToPointer(), (int)n);
+            srcSpan.CopyTo(dstSpan);
+
+            //pthread_jit_write_protect_np(1);
+
+            // Ensure that the instruction cache for this range is invalidated.
+            sys_icache_invalidate(dst, (IntPtr)n);
+        }
+
+        public static unsafe void Invalidate(IntPtr dst, ulong n)
+        {
+            // Ensure that the instruction cache for this range is invalidated.
+            sys_icache_invalidate(dst, (IntPtr)n);
+        }
+    }
 }
diff --git a/src/Ryujinx/Common/LocaleManager.cs b/src/Ryujinx/Common/LocaleManager.cs
index fafc03f69..d74de9e2d 100644
--- a/src/Ryujinx/Common/LocaleManager.cs
+++ b/src/Ryujinx/Common/LocaleManager.cs
@@ -36,6 +36,9 @@ namespace Ryujinx.Ava.Common.Locale
             var localeLanguageCode = !string.IsNullOrEmpty(ConfigurationState.Instance.UI.LanguageCode.Value) ?
                 ConfigurationState.Instance.UI.LanguageCode.Value : CultureInfo.CurrentCulture.Name.Replace('-', '_');
 
+            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
+            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
+
             // Load en_US as default, if the target language translation is missing or incomplete.
             LoadDefaultLanguage();
             LoadLanguage(localeLanguageCode);