Browse Source

Fix: generic for & pairs / ipairs

AnnulusGames 1 year ago
parent
commit
df0bc14339

+ 16 - 1
src/Lua/CodeAnalysis/Compilation/LuaCompiler.cs

@@ -895,7 +895,22 @@ public sealed class LuaCompiler : ISyntaxNodeVisitor<ScopeCompilationContext, bo
     {
         // get iterator
         var startPosition = context.StackPosition;
-        node.ExpressionNode.Accept(this, context);
+        if (node.ExpressionNode is CallFunctionExpressionNode call)
+        {
+            CompileCallFunctionExpression(call, context, false, 3);
+        }
+        else if (node.ExpressionNode is CallTableMethodExpressionNode method)
+        {
+            CompileTableMethod(method, context, false, 3);
+        }
+        else if (node.ExpressionNode is VariableArgumentsExpressionNode varArg)
+        {
+            CompileVariableArgumentsExpression(varArg, context, 3);
+        }
+        else
+        {
+            node.ExpressionNode.Accept(this, context);
+        }
 
         // jump to TFORCALL
         var startJumpIndex = context.Function.Instructions.Length;

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

@@ -781,6 +781,9 @@ public static partial class LuaVirtualMachine
                         var iterator = stack.UnsafeGet(RA).Read<LuaFunction>();
 
                         var nextBase = RA + 3 + instruction.C;
+                        stack.UnsafeGet(nextBase) = stack.UnsafeGet(RA + 1);
+                        stack.UnsafeGet(nextBase + 1) = stack.UnsafeGet(RA + 2);
+                        stack.NotifyTop(nextBase + 2);
 
                         var resultBuffer = ArrayPool<LuaValue>.Shared.Rent(1024);
                         resultBuffer.AsSpan().Clear();

+ 9 - 4
src/Lua/Standard/Basic/IPairsFunction.cs

@@ -22,16 +22,21 @@ public sealed class IPairsFunction : LuaFunction
             return function.InvokeAsync(context, buffer, cancellationToken);
         }
 
-        buffer.Span[0] = new Iterator(arg0);
-        return new(1);
+        buffer.Span[0] = Iterator.Instance;
+        buffer.Span[1] = arg0;
+        buffer.Span[2] = 0;
+        return new(3);
     }
 
-    class Iterator(LuaTable table) : LuaFunction
+    class Iterator : LuaFunction
     {
-        int i;
+        public static readonly Iterator Instance = new();
 
         protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
         {
+            var table = context.GetArgument<LuaTable>(0);
+            var i = context.GetArgument<double>(1);
+
             i++;
             if (table.TryGetValue(i, out var value))
             {

+ 4 - 16
src/Lua/Standard/Basic/PairsFunction.cs

@@ -22,21 +22,9 @@ public sealed class PairsFunction : LuaFunction
             return function.InvokeAsync(context, buffer, cancellationToken);
         }
 
-        buffer.Span[0] = new Iterator(arg0);
-        return new(1);
-    }
-
-    class Iterator(LuaTable table) : LuaFunction
-    {
-        LuaValue key;
-
-        protected override ValueTask<int> InvokeAsyncCore(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken)
-        {
-            var kv = table.GetNext(key);
-            buffer.Span[0] = kv.Key;
-            buffer.Span[1] = kv.Value;
-            key = kv.Key;
-            return new(2);
-        }
+        buffer.Span[0] = NextFunction.Instance;
+        buffer.Span[1] = arg0;
+        buffer.Span[2] = LuaValue.Nil;
+        return new(3);
     }
 }