Browse Source

Add: LuaValue.UnsafeRead

AnnulusGames 1 year ago
parent
commit
9323ec4164

+ 4 - 4
src/Lua/LuaState.cs

@@ -109,8 +109,8 @@ public sealed class LuaState
             LuaValueType.Number => numberMetatable,
             LuaValueType.Function => functionMetatable,
             LuaValueType.Thread => threadMetatable,
-            LuaValueType.UserData => value.Read<LuaUserData>().Metatable,
-            LuaValueType.Table => value.Read<LuaTable>().Metatable,
+            LuaValueType.UserData => value.UnsafeRead<LuaUserData>().Metatable,
+            LuaValueType.Table => value.UnsafeRead<LuaTable>().Metatable,
             _ => null
         };
 
@@ -141,10 +141,10 @@ public sealed class LuaState
                 threadMetatable = metatable;
                 break;
             case LuaValueType.UserData:
-                value.Read<LuaUserData>().Metatable = metatable;
+                value.UnsafeRead<LuaUserData>().Metatable = metatable;
                 break;
             case LuaValueType.Table:
-                value.Read<LuaTable>().Metatable = metatable;
+                value.UnsafeRead<LuaTable>().Metatable = metatable;
                 break;
         }
     }

+ 1 - 1
src/Lua/LuaTable.cs

@@ -41,7 +41,7 @@ public sealed class LuaTable
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         set
         {
-            if (key.Type is LuaValueType.Number && double.IsNaN(key.Read<double>()))
+            if (key.Type is LuaValueType.Number && double.IsNaN(key.UnsafeRead<double>()))
             {
                 ThrowIndexIsNaN();
             }

+ 29 - 1
src/Lua/LuaValue.cs

@@ -28,7 +28,6 @@ public readonly struct LuaValue : IEquatable<LuaValue>
 
     public LuaValueType Type => type;
 
-    [MethodImpl(MethodImplOptions.AggressiveInlining)]
     public bool TryRead<T>(out T result)
     {
         var t = typeof(T);
@@ -211,6 +210,35 @@ public readonly struct LuaValue : IEquatable<LuaValue>
         return result;
     }
 
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    internal T UnsafeRead<T>()
+    {
+        switch (type)
+        {
+            case LuaValueType.Boolean:
+                {
+                    var v = value == 1;
+                    return Unsafe.As<bool, T>(ref v);
+                }
+            case LuaValueType.Number:
+                {
+                    var v = value;
+                    return Unsafe.As<double, T>(ref v);
+                }
+            case LuaValueType.String:
+            case LuaValueType.Thread:
+            case LuaValueType.Function:
+            case LuaValueType.Table:
+            case LuaValueType.UserData:
+                {
+                    var v = referenceValue!;
+                    return Unsafe.As<object, T>(ref v);
+                }
+        }
+
+        return default!;
+    }
+
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     public bool ToBoolean()
     {

+ 0 - 18
src/Lua/Runtime/LuaValueRuntimeExtensions.cs

@@ -1,4 +1,3 @@
-using System.Buffers;
 using System.Runtime.CompilerServices;
 
 namespace Lua.Runtime;
@@ -20,21 +19,4 @@ internal static class LuaRuntimeExtensions
             ? argumentCount - luaClosure.Proto.ParameterCount
             : 0;
     }
-
-#if NET6_0_OR_GREATER
-    [AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder<>))]
-#endif
-    public static async ValueTask<int> InvokeAsync(this LuaFunction function, LuaFunctionExecutionContext context, CancellationToken cancellationToken)
-    {
-        var buffer = ArrayPool<LuaValue>.Shared.Rent(1024);
-        buffer.AsSpan().Clear();
-        try
-        {
-            return await function.InvokeAsync(context, buffer, cancellationToken);
-        }
-        finally
-        {
-            ArrayPool<LuaValue>.Shared.Return(buffer);
-        }
-    }
 }

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

@@ -996,9 +996,13 @@ public static partial class LuaVirtualMachine
         var stack = thread.Stack;
         var isTable = table.TryRead<LuaTable>(out var t);
 
-        if (key.Type is LuaValueType.Number && key.TryRead<double>(out var d) && double.IsNaN(d))
+        if (key.Type is LuaValueType.Number)
         {
-            throw new LuaRuntimeException(GetTracebacks(state, chunk, pc), "table index is NaN");
+            var d = key.UnsafeRead<double>();
+            if (double.IsNaN(d))
+            {
+                throw new LuaRuntimeException(GetTracebacks(state, chunk, pc), "table index is NaN");
+            }
         }
 
         if (isTable)

+ 1 - 1
src/Lua/Standard/Basic/ToNumberFunction.cs

@@ -22,7 +22,7 @@ public sealed class ToNumberFunction : LuaFunction
         double? value = null;
         if (e.Type is LuaValueType.Number)
         {
-            value = e.Read<double>();
+            value = e.UnsafeRead<double>();
         }
         else if (e.TryRead<string>(out var str))
         {