Browse Source

fix: error message LuaValueType

Akeit0 6 months ago
parent
commit
25f03850ba

+ 63 - 9
src/Lua/Exceptions.cs

@@ -121,7 +121,14 @@ public class LuaRuntimeException : Exception, ILuaTracebackBuildable
 
     public static void AttemptInvalidOperation(LuaThread? thread, string op, LuaValue a, LuaValue b)
     {
-        throw new LuaRuntimeException(thread, $"attempt to {op} a {a.TypeToString()} value with a {b.TypeToString()} value");
+        var typeA = a.TypeToString();
+        var typeB = b.TypeToString();
+        if (typeA == typeB)
+        {
+            throw new LuaRuntimeException(thread, $"attempt to {op} two {typeA} values");
+        }
+ 
+        throw new LuaRuntimeException(thread, $"attempt to {op} a {typeA} value with a {typeB} value");
     }
 
     public static void AttemptInvalidOperation(LuaThread? thread, string op, LuaValue a)
@@ -129,28 +136,70 @@ public class LuaRuntimeException : Exception, ILuaTracebackBuildable
         throw new LuaRuntimeException(thread, $"attempt to {op} a {a.TypeToString()} value");
     }
 
+    internal static void AttemptInvalidOperationOnLuaStack(LuaThread thread, string op, int lastPc, int regA, int regB)
+    {
+        var caller = thread.GetCurrentFrame();
+        var luaValueA = regA < 255 ? thread.Stack[caller.Base + regA] : ((LuaClosure)caller.Function).Proto.Constants[regA - 256];
+        var luaValueB = regB < 255 ? thread.Stack[caller.Base + regB] : ((LuaClosure)caller.Function).Proto.Constants[regB - 256];
+        var function = caller.Function;
+        var tA = LuaDebug.GetName(((LuaClosure)function).Proto, lastPc, regA, out string? nameA);
+        var tB = LuaDebug.GetName(((LuaClosure)function).Proto, lastPc, regB, out string? nameB);
+
+        using var builder = new PooledList<char>(64);
+        builder.Clear();
+        builder.AddRange("attempt to ");
+        builder.AddRange(op);
+        builder.AddRange(" a ");
+        builder.AddRange(luaValueA.TypeToString());
+        builder.AddRange(" value");
+        if (tA != null && nameA != null)
+        {
+            builder.AddRange($" ({tA} '{nameA}')");
+        }
+
+        builder.AddRange(" with a ");
+        builder.AddRange(luaValueB.TypeToString());
+        builder.AddRange(" value");
+        if (tB != null && nameB != null)
+        {
+            builder.AddRange($" ({tB} '{nameB}')");
+        }
+
+        throw new LuaRuntimeException(thread, builder.AsSpan().ToString());
+    }
+
     internal static void AttemptInvalidOperationOnLuaStack(LuaThread thread, string op, int lastPc, int reg)
     {
         var caller = thread.GetCurrentFrame();
-        var luaValue = thread.Stack[caller.Base + reg];
+        var luaValue = reg < 255 ? thread.Stack[caller.Base + reg] : ((LuaClosure)caller.Function).Proto.Constants[reg - 256];
         var function = caller.Function;
         var t = LuaDebug.GetName(((LuaClosure)function).Proto, lastPc, reg, out string? name);
-        if (t == null || name == null)
+        
+        using var builder = new PooledList<char>(64);
+        builder.Clear();
+        builder.AddRange("attempt to ");
+        builder.AddRange(op);
+        builder.AddRange(" a ");
+        builder.AddRange(luaValue.TypeToString());
+        builder.AddRange(" value");
+        if (t != null && name != null)
         {
-            throw new LuaRuntimeException(thread, $"attempt to {op} a {luaValue.TypeToString()} value");
+            builder.AddRange($" ({t} '{name}')");
         }
-        else
         {
-            throw new LuaRuntimeException(thread, $"attempt to {op} a {luaValue.TypeToString()} value ({t} '{name}')");
+            throw new LuaRuntimeException(thread,  builder.AsSpan().ToString());
         }
     }
 
     internal static void AttemptInvalidOperationOnUpValues(LuaThread thread, string op, int lastPc, int reg)
     {
         var caller = thread.GetCurrentFrame();
-        var luaValue = thread.Stack[caller.Base + reg];
-        var function = caller.Function;
-        var name = ((LuaClosure)function).Proto.UpValues[reg].Name;
+        var closure = (LuaClosure)caller.Function;
+        var proto = closure.Proto;
+
+        var upValue = proto.UpValues[reg];
+        var luaValue = closure.UpValues[upValue.Index].GetValue();
+        var name = upValue.Name;
 
         throw new LuaRuntimeException(thread, $"attempt to {op} a {luaValue.TypeToString()} value (global '{name}')");
     }
@@ -169,6 +218,11 @@ public class LuaRuntimeException : Exception, ILuaTracebackBuildable
     {
         throw new LuaRuntimeException(thread, $"bad argument #{argumentId} to '{functionName}' ({expected} expected, got {actual})");
     }
+    
+    public static void BadArgument(LuaThread? thread, int argumentId, string functionName, LuaValueType expected, LuaValueType actual)
+    {
+        throw new LuaRuntimeException(thread, $"bad argument #{argumentId} to '{functionName}' ({LuaValue.ToString(expected)} expected, got {LuaValue.ToString(actual)})");
+    }
 
     public static void BadArgument(LuaThread? thread, int argumentId, string functionName, string message)
     {

+ 1 - 1
src/Lua/Internal/LuaDebug.cs

@@ -434,7 +434,7 @@ internal readonly struct LuaDebug : IDisposable
                         int t = i.B; /* table index */
 
                         var vn = (op == OpCode.GetTable) /* name of indexed variable */
-                            ? GetLocalName(prototype, t + 1, pc)
+                            ? GetLocalName(prototype, t, pc)
                             : prototype.UpValues[t].Name.ToString();
                         GetConstantName(prototype, pc, k, out name);
                         return vn is "_ENV" ? "global" : "field";

+ 4 - 4
src/Lua/LuaFunctionExecutionContext.cs

@@ -63,7 +63,7 @@ public readonly record struct LuaFunctionExecutionContext
             }
             else if (LuaValue.TryGetLuaValueType(t, out var type))
             {
-                LuaRuntimeException.BadArgument(Thread, index + 1, Thread.GetCurrentFrame().Function.Name, type.ToString(), arg.Type.ToString());
+                LuaRuntimeException.BadArgument(Thread, index + 1, Thread.GetCurrentFrame().Function.Name, type, arg.Type);
             }
             else if (arg.Type is LuaValueType.UserData or LuaValueType.LightUserData)
             {
@@ -71,7 +71,7 @@ public readonly record struct LuaFunctionExecutionContext
             }
             else
             {
-                LuaRuntimeException.BadArgument(Thread, index + 1, Thread.GetCurrentFrame().Function.Name, t.Name, arg.Type.ToString());
+                LuaRuntimeException.BadArgument(Thread, index + 1, Thread.GetCurrentFrame().Function.Name, t.Name, arg.TypeToString());
             }
         }
 
@@ -102,7 +102,7 @@ public readonly record struct LuaFunctionExecutionContext
             }
             else if (LuaValue.TryGetLuaValueType(t, out var type))
             {
-                LuaRuntimeException.BadArgument(Thread, index + 1, Thread.GetCurrentFrame().Function.Name, type.ToString(), arg.Type.ToString());
+                LuaRuntimeException.BadArgument(Thread, index + 1, Thread.GetCurrentFrame().Function.Name, type, arg.Type);
             }
             else if (arg.Type is LuaValueType.UserData or LuaValueType.LightUserData)
             {
@@ -110,7 +110,7 @@ public readonly record struct LuaFunctionExecutionContext
             }
             else
             {
-                LuaRuntimeException.BadArgument(Thread, index + 1, Thread.GetCurrentFrame().Function.Name, t.Name, arg.Type.ToString());
+                LuaRuntimeException.BadArgument(Thread, index + 1, Thread.GetCurrentFrame().Function.Name, t.Name, arg.TypeToString());
             }
         }
 

+ 2 - 14
src/Lua/LuaValue.cs

@@ -576,19 +576,7 @@ public readonly struct LuaValue : IEquatable<LuaValue>
 
     public string TypeToString()
     {
-        return Type switch
-        {
-            LuaValueType.Nil => "nil",
-            LuaValueType.Boolean => "boolean",
-            LuaValueType.String => "string",
-            LuaValueType.Number => "number",
-            LuaValueType.Function => "function",
-            LuaValueType.Thread => "thread",
-            LuaValueType.Table => "table",
-            LuaValueType.LightUserData => "userdata",
-            LuaValueType.UserData => "userdata",
-            _ => "",
-        };
+        return ToString(Type);
     }
 
     public static string ToString(LuaValueType type)
@@ -602,7 +590,7 @@ public readonly struct LuaValue : IEquatable<LuaValue>
             LuaValueType.Function => "function",
             LuaValueType.Thread => "thread",
             LuaValueType.Table => "table",
-            LuaValueType.LightUserData => "userdata",
+            LuaValueType.LightUserData => "light userdata",
             LuaValueType.UserData => "userdata",
             _ => "",
         };

+ 3 - 3
src/Lua/Runtime/LuaVirtualMachine.cs

@@ -1901,7 +1901,7 @@ public static partial class LuaVirtualMachine
             return true;
         }
 
-        LuaRuntimeException.AttemptInvalidOperation(GetThreadWithCurrentPc(context), description, vb, vc);
+        LuaRuntimeException.AttemptInvalidOperationOnLuaStack(GetThreadWithCurrentPc(context), description,context.Pc, context.Instruction.B, context.Instruction.C);
         return false;
     }
 
@@ -2035,7 +2035,7 @@ public static partial class LuaVirtualMachine
             return true;
         }
 
-        LuaRuntimeException.AttemptInvalidOperation(GetThreadWithCurrentPc(context), description, vb);
+        LuaRuntimeException.AttemptInvalidOperationOnLuaStack(GetThreadWithCurrentPc(context), description,context.Pc, context.Instruction.B);
         return true;
     }
 
@@ -2186,7 +2186,7 @@ public static partial class LuaVirtualMachine
                 (vb, vc) = (vc, vb);
             }
 
-            LuaRuntimeException.AttemptInvalidOperation(GetThreadWithCurrentPc(context), description, vb, vc);
+            LuaRuntimeException.AttemptInvalidOperation(GetThreadWithCurrentPc(context), "compare", vb, vc);
         }
         else
         {

+ 1 - 1
src/Lua/Standard/BasicLibrary.cs

@@ -350,7 +350,7 @@ public sealed class BasicLibrary
         }
         else
         {
-            LuaRuntimeException.BadArgument(context.Thread, 1, "select", "number", arg0.Type.ToString());
+            LuaRuntimeException.BadArgument(context.Thread, 1, "select", LuaValueType.Number, arg0.Type);
             return default;
         }
     }

+ 1 - 1
src/Lua/Standard/OperatingSystemLibrary.cs

@@ -121,7 +121,7 @@ public sealed class OperatingSystemLibrary
             }
             else
             {
-                LuaRuntimeException.BadArgument(context.Thread, 1, "exit", LuaValueType.Nil.ToString(), code.Type.ToString());
+                LuaRuntimeException.BadArgument(context.Thread, 1, "exit", LuaValueType.Nil, code.Type);
             }
         }
         else

+ 2 - 2
src/Lua/Standard/StringLibrary.cs

@@ -243,7 +243,7 @@ public sealed class StringLibrary
                     case 'G':
                         if (!parameter.TryRead<double>(out var f))
                         {
-                            LuaRuntimeException.BadArgument(context.Thread, parameterIndex + 1, "format", LuaValueType.Number.ToString(), parameter.Type.ToString());
+                            LuaRuntimeException.BadArgument(context.Thread, parameterIndex + 1, "format", LuaValueType.Number, parameter.Type);
                         }
 
                         switch (specifier)
@@ -324,7 +324,7 @@ public sealed class StringLibrary
                     case 'X':
                         if (!parameter.TryRead<double>(out var x))
                         {
-                            LuaRuntimeException.BadArgument(context.Thread, parameterIndex + 1, "format", LuaValueType.Number.ToString(), parameter.Type.ToString());
+                            LuaRuntimeException.BadArgument(context.Thread, parameterIndex + 1, "format", LuaValueType.Number, parameter.Type);
                         }
 
                         LuaRuntimeException.ThrowBadArgumentIfNumberIsNotInteger(context.Thread, "format", parameterIndex + 1, x);