diff --git a/sandbox/Benchmark/CoroutineBenchmark.cs b/sandbox/Benchmark/CoroutineBenchmark.cs index 47595dc..9e24d45 100644 --- a/sandbox/Benchmark/CoroutineBenchmark.cs +++ b/sandbox/Benchmark/CoroutineBenchmark.cs @@ -14,6 +14,7 @@ public void GlobalSetup() { core.Setup("coroutine.lua"); core.LuaCSharpState.OpenBasicLibrary(); + core.LuaCSharpState.OpenCoroutineLibrary(); } [Benchmark(Description = "MoonSharp (RunString)")] diff --git a/src/Lua/LuaCoroutine.cs b/src/Lua/LuaCoroutine.cs index 6eb1f0c..3e39e30 100644 --- a/src/Lua/LuaCoroutine.cs +++ b/src/Lua/LuaCoroutine.cs @@ -60,9 +60,10 @@ public override async ValueTask ResumeAsync(LuaFunctionExecutionContext con if (isFirstCall) { // copy stack value - Stack.EnsureCapacity(baseThread.Stack.Count); - baseThread.Stack.AsSpan().CopyTo(Stack.GetBuffer()); - Stack.NotifyTop(baseThread.Stack.Count); + var argCount = context.ArgumentCount; + Stack.EnsureCapacity(argCount); + baseThread.Stack.AsSpan()[^argCount..].CopyTo(Stack.GetBuffer()); + Stack.NotifyTop(argCount); } else { @@ -122,27 +123,19 @@ public override async ValueTask ResumeAsync(LuaFunctionExecutionContext con if (variableArgumentCount > 0) { var fixedArgumentCount = context.ArgumentCount - 1 - variableArgumentCount; + var args = context.Arguments; - for (int i = 0; i < variableArgumentCount; i++) - { - Stack.Push(context.GetArgument(i + fixedArgumentCount + 1)); - } + Stack.PushRange(args.Slice(1 + fixedArgumentCount, variableArgumentCount)); frameBase = Stack.Count; - for (int i = 0; i < fixedArgumentCount; i++) - { - Stack.Push(context.GetArgument(i + 1)); - } + Stack.PushRange(args.Slice(1, fixedArgumentCount)); } else { frameBase = Stack.Count; - for (int i = 0; i < context.ArgumentCount - 1; i++) - { - Stack.Push(context.GetArgument(i + 1)); - } + Stack.PushRange(context.Arguments[1..]); } functionTask = Function.InvokeAsync(new() @@ -156,17 +149,15 @@ public override async ValueTask ResumeAsync(LuaFunctionExecutionContext con Volatile.Write(ref isFirstCall, false); } - (var index, var result0, var result1) = await ValueTaskEx.WhenAny(resumeTask, functionTask!); + var (index, result0, result1) = await ValueTaskEx.WhenAny(resumeTask, functionTask!); + var bufferSpan = buffer.Span; if (index == 0) { var results = result0.Results; - buffer.Span[0] = true; - for (int i = 0; i < results.Length; i++) - { - buffer.Span[i + 1] = results[i]; - } + bufferSpan[0] = true; + results.CopyTo(bufferSpan[1..]); return results.Length + 1; } @@ -175,8 +166,8 @@ public override async ValueTask ResumeAsync(LuaFunctionExecutionContext con var resultCount = functionTask!.Result; Volatile.Write(ref status, (byte)LuaThreadStatus.Dead); - buffer.Span[0] = true; - this.buffer[0..resultCount].CopyTo(buffer.Span[1..]); + bufferSpan[0] = true; + this.buffer.AsSpan()[..resultCount].CopyTo(bufferSpan[1..]); ArrayPool.Shared.Return(this.buffer); @@ -191,7 +182,7 @@ public override async ValueTask ResumeAsync(LuaFunctionExecutionContext con Volatile.Write(ref status, (byte)LuaThreadStatus.Dead); buffer.Span[0] = false; - buffer.Span[1] = ex is LuaRuntimeException { ErrorObject: not null } luaEx ? luaEx.ErrorObject.Value: ex.Message; + buffer.Span[1] = ex is LuaRuntimeException { ErrorObject: not null } luaEx ? luaEx.ErrorObject.Value : ex.Message; return 2; } else