Quellcode durchsuchen

fix: unary meta method retur

akeit0 vor 1 Woche
Ursprung
Commit
f535577114
2 geänderte Dateien mit 38 neuen und 10 gelöschten Zeilen
  1. 12 10
      src/Lua/Runtime/LuaVirtualMachine.cs
  2. 26 0
      tests/Lua.Tests/LuaObjectTests.cs

+ 12 - 10
src/Lua/Runtime/LuaVirtualMachine.cs

@@ -1979,7 +1979,7 @@ public static partial class LuaVirtualMachine
             stack.Push(vc);
             var (argCount, variableArgumentCount) = PrepareForFunctionCall(context.State, func, newBase);
             newBase += variableArgumentCount;
-            var newFrame = func.CreateNewFrame(context, newBase, newBase, variableArgumentCount);
+            var newFrame = func.CreateNewFrame(context, newBase, context.Instruction.A + context.FrameBase, variableArgumentCount);
 
             context.State.PushCallStackFrame(newFrame);
             if (context.State.CallOrReturnHookMask.Value != 0 && !context.State.IsInHook)
@@ -2008,10 +2008,11 @@ public static partial class LuaVirtualMachine
                 return false;
             }
 
-            stack.Get(context.Instruction.A + context.FrameBase)
-                = task.GetAwaiter().GetResult() != 0
-                    ? stack.FastGet(newFrame.ReturnBase)
-                    : default;
+            if (task.GetAwaiter().GetResult() == 0)
+            {
+                stack.Get(newFrame.ReturnBase) = default;
+            }
+
             stack.PopUntil(newFrame.ReturnBase + 1);
             context.State.PopCallStackFrame();
             return true;
@@ -2107,7 +2108,7 @@ public static partial class LuaVirtualMachine
             var (argCount, variableArgumentCount) = PrepareForFunctionCall(context.State, func, newBase);
             newBase += variableArgumentCount;
 
-            var newFrame = func.CreateNewFrame(context, newBase, newBase, variableArgumentCount);
+            var newFrame = func.CreateNewFrame(context, newBase, context.Instruction.A + context.FrameBase, variableArgumentCount);
 
             context.State.PushCallStackFrame(newFrame);
             if (context.State.CallOrReturnHookMask.Value != 0 && !context.State.IsInHook)
@@ -2136,10 +2137,11 @@ public static partial class LuaVirtualMachine
                 return false;
             }
 
-            var result = stack.Count > newFrame.ReturnBase
-                ? stack.Get(newFrame.ReturnBase)
-                : default;
-            stack.Get(context.Instruction.A + context.FrameBase) = result;
+            if (task.GetAwaiter().GetResult() == 0)
+            {
+                stack.Get(newFrame.ReturnBase) = default;
+            }
+
             stack.PopUntil(newFrame.ReturnBase + 1);
             context.State.PopCallStackFrame();
             return true;

+ 26 - 0
tests/Lua.Tests/LuaObjectTests.cs

@@ -41,6 +41,13 @@ public partial class LuaTestObj
         return new LuaTestObj() { x = a.x - b.x, y = a.y - b.y };
     }
 
+    [LuaMetamethod(LuaObjectMetamethod.Len)]
+    public async Task<double> Len()
+    {
+        await Task.Delay(1);
+        return x + y;
+    }
+
     [LuaMember]
     public object GetObj() => this;
 }
@@ -228,4 +235,23 @@ public class LuaObjectTests
         Assert.That(objSub.X, Is.EqualTo(-2));
         Assert.That(objSub.Y, Is.EqualTo(-2));
     }
+
+    [Test]
+    public async Task Test_LenMetamethod()
+    {
+        var userData = new LuaTestObj();
+
+        var state = LuaState.Create();
+        state.OpenBasicLibrary();
+        state.Environment["TestObj"] = userData;
+        var results = await state.DoStringAsync("""
+                                                function testLen(obj)
+                                                    local ret=  #obj
+                                                    return ret
+                                                end
+                                                return testLen(TestObj.create(1, 2))
+                                                """);
+        Assert.That(results, Has.Length.EqualTo(1));
+        Assert.That(results[0].Read<double>(), Is.EqualTo(3));
+    }
 }