2
0
AnnulusGames 1 жил өмнө
parent
commit
d0acaa547d

+ 18 - 0
src/Lua/Internal/MemoryMarshalEx.cs

@@ -0,0 +1,18 @@
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Lua.Internal;
+
+internal static class MemoryMarshalEx
+{
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    public static ref T UnsafeElementAt<T>(T[] array, int index)
+    {
+#if NET6_0_OR_GREATER
+        return ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), index);
+#else
+        ref var reference = ref MemoryMarshal.GetReference(array.AsSpan());
+        return ref Unsafe.Add(ref reference, index);
+#endif
+    }
+}

+ 8 - 6
src/Lua/LuaTable.cs

@@ -33,7 +33,7 @@ public sealed class LuaTable
                 if (index > 0 && index <= array.Length)
                 {
                     // Arrays in Lua are 1-origin...
-                    return array[index - 1];
+                    return MemoryMarshalEx.UnsafeElementAt(array, index - 1);
                 }
             }
 
@@ -52,7 +52,7 @@ public sealed class LuaTable
                 if (0 < index && index <= Math.Max(array.Length * 2, 8))
                 {
                     EnsureArrayCapacity(index);
-                    array[index - 1] = value;
+                    MemoryMarshalEx.UnsafeElementAt(array, index - 1) = value;
                     return;
                 }
             }
@@ -96,7 +96,7 @@ public sealed class LuaTable
         {
             if (index > 0 && index <= array.Length)
             {
-                value = array[index - 1];
+                value = MemoryMarshalEx.UnsafeElementAt(array, index - 1);
                 return value.Type is not LuaValueType.Nil;
             }
         }
@@ -113,7 +113,8 @@ public sealed class LuaTable
 
         if (TryGetInteger(key, out var index))
         {
-            return index > 0 && index <= array.Length && array[index - 1].Type != LuaValueType.Nil;
+            return index > 0 && index <= array.Length &&
+                MemoryMarshalEx.UnsafeElementAt(array, index - 1).Type != LuaValueType.Nil;
         }
 
         return dictionary.TryGetValue(key, out var value) && value.Type is not LuaValueType.Nil;
@@ -127,13 +128,14 @@ public sealed class LuaTable
         }
 
         var arrayIndex = index - 1;
-        var value = array[arrayIndex];
+        var value = MemoryMarshalEx.UnsafeElementAt(array, arrayIndex);
 
         if (arrayIndex < array.Length - 1)
         {
             array.AsSpan(arrayIndex + 1).CopyTo(array.AsSpan(arrayIndex));
         }
-        array[^1] = default;
+        
+        MemoryMarshalEx.UnsafeElementAt(array, array.Length - 1) = default;
 
         return value;
     }

+ 2 - 9
src/Lua/Runtime/LuaStack.cs

@@ -1,5 +1,5 @@
 using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+using Lua.Internal;
 
 namespace Lua.Runtime;
 
@@ -91,14 +91,7 @@ public class LuaStack(int initialSize = 256)
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     public ref LuaValue UnsafeGet(int index)
     {
-        // if (index < 0 || index >= array.Length) throw new IndexOutOfRangeException();
-
-#if NET6_0_OR_GREATER
-        return ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(array), index);
-#else
-        ref var reference = ref MemoryMarshal.GetReference(array.AsSpan());
-        return ref Unsafe.Add(ref reference, index);
-#endif
+        return ref MemoryMarshalEx.UnsafeElementAt(array, index);
     }
 
     static void ThrowEmptyStack()

+ 1 - 6
src/Lua/Runtime/LuaVirtualMachine.cs

@@ -920,12 +920,7 @@ public static partial class LuaVirtualMachine
     {
         if (index >= 256)
         {
-#if NET6_0_OR_GREATER
-            return ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(chunk.Constants), index - 256);
-#else
-            ref var reference = ref MemoryMarshal.GetReference(chunk.Constants.AsSpan());
-            return ref Unsafe.Add(ref reference, index - 256);
-#endif
+            return ref MemoryMarshalEx.UnsafeElementAt(chunk.Constants, index - 256);
         }
         else
         {