diff --git a/src/Lua/Standard/BasicLibrary.cs b/src/Lua/Standard/BasicLibrary.cs index f1bbab98..563b4e22 100644 --- a/src/Lua/Standard/BasicLibrary.cs +++ b/src/Lua/Standard/BasicLibrary.cs @@ -9,6 +9,20 @@ namespace Lua.Standard; public sealed class BasicLibrary { public static readonly BasicLibrary Instance = new(); + static readonly HashSet KnownCollectGarbageOptions = + [ + "collect", + "stop", + "restart", + "count", + "step", + "setpause", + "setstepmul", + "setmajorinc", + "isrunning", + "incremental", + "generational" + ]; public BasicLibrary() { @@ -83,7 +97,13 @@ public ValueTask CollectGarbage(LuaFunctionExecutionContext context, Cancel { if (context.HasArgument(0)) { - context.GetArgument(0); + var option = context.GetArgument(0); + if (!KnownCollectGarbageOptions.Contains(option)) + { + throw new LuaRuntimeException(context.State, "bad argument #1 to 'collectgarbage' (invalid option)"); + } + + // TODO: Implement Lua-compatible behavior for each collectgarbage option. } GC.Collect(); diff --git a/src/Lua/Standard/FileHandle.cs b/src/Lua/Standard/FileHandle.cs index c546a4aa..3870ce36 100644 --- a/src/Lua/Standard/FileHandle.cs +++ b/src/Lua/Standard/FileHandle.cs @@ -48,6 +48,7 @@ static FileHandle() { fileHandleMetatable = new(0, 1); fileHandleMetatable[Metamethods.Index] = IndexMetamethod; + fileHandleMetatable["__gc"] = GcFunction; fileHandleMetatable["__tostring"] = ToStringFunction; } @@ -233,4 +234,14 @@ public async ValueTask Close(CancellationToken cancellationToken) var file = context.GetArgument(0); return new(context.Return($"file ({(file.IsOpen ? file.stream.GetHashCode() : "closed")})")); }); -} \ No newline at end of file + + static readonly LuaFunction GcFunction = new("file.__gc", (context, cancellationToken) => + { + if (!context.HasArgument(0)) + { + throw new LuaRuntimeException(context.State, "bad argument #1 to '__gc' (no value)"); + } + + return new(context.Return()); + }); +}