Browse Source

Merge pull request #231 from nuskey8/meta-pairs

fix: support __pairs/__ipairs for non-table type
akeit0 4 days ago
parent
commit
1ab1f4fe67
1 changed files with 14 additions and 4 deletions
  1. 14 4
      src/Lua/Standard/BasicLibrary.cs

+ 14 - 4
src/Lua/Standard/BasicLibrary.cs

@@ -135,10 +135,10 @@ public sealed class BasicLibrary
 
 
     public async ValueTask<int> IPairs(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public async ValueTask<int> IPairs(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     {
     {
-        var arg0 = context.GetArgument<LuaTable>(0);
+        var arg0 = context.GetArgument(0);
 
 
         // If table has a metamethod __ipairs, calls it with table as argument and returns the first three results from the call.
         // If table has a metamethod __ipairs, calls it with table as argument and returns the first three results from the call.
-        if (arg0.Metatable != null && arg0.Metatable.TryGetValue(Metamethods.IPairs, out var metamethod))
+        if (context.State.GlobalState.TryGetMetatable(arg0,out var metaTable) && metaTable.TryGetValue(Metamethods.IPairs, out var metamethod))
         {
         {
             var stack = context.State.Stack;
             var stack = context.State.Stack;
             var top = stack.Count;
             var top = stack.Count;
@@ -150,6 +150,11 @@ public sealed class BasicLibrary
             return 3;
             return 3;
         }
         }
 
 
+        if (arg0.Type != LuaValueType.Table)
+        {
+            LuaRuntimeException.BadArgument(context.State, 1, LuaValueType.Table, arg0.Type);
+        }
+
         return context.Return(IPairsIterator, arg0, 0);
         return context.Return(IPairsIterator, arg0, 0);
     }
     }
 
 
@@ -232,10 +237,10 @@ public sealed class BasicLibrary
 
 
     public async ValueTask<int> Pairs(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     public async ValueTask<int> Pairs(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
     {
     {
-        var arg0 = context.GetArgument<LuaTable>(0);
+        var arg0 = context.GetArgument(0);
 
 
         // If table has a metamethod __pairs, calls it with table as argument and returns the first three results from the call.
         // If table has a metamethod __pairs, calls it with table as argument and returns the first three results from the call.
-        if (arg0.Metatable != null && arg0.Metatable.TryGetValue(Metamethods.Pairs, out var metamethod))
+        if (context.State.GlobalState.TryGetMetatable(arg0, out var metaTable) && metaTable.TryGetValue(Metamethods.Pairs, out var metamethod))
         {
         {
             var stack = context.State.Stack;
             var stack = context.State.Stack;
             var top = stack.Count;
             var top = stack.Count;
@@ -247,6 +252,11 @@ public sealed class BasicLibrary
             return 3;
             return 3;
         }
         }
 
 
+        if (arg0.Type != LuaValueType.Table)
+        {
+            LuaRuntimeException.BadArgument(context.State, 1, LuaValueType.Table, arg0.Type);
+        }
+
         return context.Return(PairsIterator, arg0, LuaValue.Nil);
         return context.Return(PairsIterator, arg0, LuaValue.Nil);
     }
     }