Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions sandbox/Benchmark/InterpreterSteps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ public LuaClosure Compile()
[Benchmark]
public async ValueTask RunAsync()
{
await state.MainThread.RunAsync(closure);
state.MainThread.Stack.Clear();
await state.TopLevelAccess.Call(closure, []);
}
}
64 changes: 42 additions & 22 deletions sandbox/ConsoleApp1/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Text.RegularExpressions;
using System;
using System.IO;

using System.Text;
var state = LuaState.Create();
state.OpenStandardLibraries();

Expand All @@ -31,10 +31,10 @@

Console.WriteLine("Output " + new string('-', 50));

var count = await state.MainThread.RunAsync(closure);
var count = await state.TopLevelAccess.RunAsync(closure);

Console.WriteLine("Result " + new string('-', 50));
using var results = state.MainThread.ReadReturnValues(count);
using var results = state.TopLevelAccess.ReadReturnValues(count);
for (int i = 0; i < count; i++)
{
Console.WriteLine(results[i]);
Expand All @@ -46,26 +46,10 @@
{
if (ex is LuaCompileException luaCompileException)
{
var linOffset = luaCompileException.OffSet - luaCompileException.Position.Column + 1;
var length = 0;
foreach (var c in source.AsSpan(linOffset))
{
if (c is '\n' or '\r')
{
break;
}

length++;
}


Console.WriteLine("CompileError " + new string('-', 50));
Console.WriteLine(luaCompileException.ChunkName + ":"+luaCompileException.Position.Line + ":" + luaCompileException.Position.Column);
var line = source.Substring(linOffset, length);
var lineNumString = luaCompileException.Position.Line.ToString();
Console.WriteLine(new string(' ', lineNumString.Length) + " |");
Console.WriteLine(lineNumString + " | " + line);
Console.WriteLine(new string(' ', lineNumString.Length) + " | " +
new string(' ', luaCompileException.Position.Column - 1) +
"^ " + luaCompileException.MainMessage);
Console.WriteLine(RustLikeExceptionHook.OnCatch(source, luaCompileException)); ;
Console.WriteLine(new string('-', 55));
}

Expand Down Expand Up @@ -128,4 +112,40 @@ static void DebugChunk(Prototype chunk, int id)
DebugChunk(localChunk, nestedChunkId);
nestedChunkId++;
}
}

public class LuaRustLikeException(string message, Exception? innerException) : LuaException(message, innerException);

class RustLikeExceptionHook //: ILuaCompileHook
{
public static string OnCatch(ReadOnlySpan<char> source, LuaCompileException exception)
{
var lineOffset = exception.OffSet - exception.Position.Column + 1;
var length = 0;
if (lineOffset < 0)
{
lineOffset = 0;
}
foreach (var c in source[lineOffset..])
{
if (c is '\n' or '\r')
{
break;
}

length++;
}
var builder = new StringBuilder();
builder.AppendLine();
builder.AppendLine("[error]: "+exception.MessageWithNearToken);
builder.AppendLine("-->"+exception.ChunkName + ":" + exception.Position.Line + ":" + exception.Position.Column);
var line = source.Slice(lineOffset, length).ToString();
var lineNumString = exception.Position.Line.ToString();
builder.AppendLine(new string(' ', lineNumString.Length) + " |");
builder.AppendLine(lineNumString + " | " + line);
builder.AppendLine(new string(' ', lineNumString.Length) + " | " +
new string(' ', exception.Position.Column - 1) +
"^ " + exception.MainMessage);
return builder.ToString();
}
}
12 changes: 6 additions & 6 deletions sandbox/ConsoleApp2/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
{
var closure = state.Load("return function (a,b,...) print('a : '..a..' b :'..'args : ',...) end", "simple");
using var threadLease = state.MainThread.RentUseThread();
var thread = threadLease.Thread;
var access = threadLease.Thread.TopLevelAccess;
{
var count = await thread.RunAsync(closure);
var results = thread.ReadReturnValues(count);
var count = await access.RunAsync(closure,0);
var results = access.ReadReturnValues(count);
for (int i = 0; i < results.Length; i++)
{
Console.WriteLine(results[i]);
}

var f = results[0].Read<LuaClosure>();
results.Dispose();
thread.Push("hello", "world", 1, 2, 3);
count = await thread.RunAsync(f);
results = thread.ReadReturnValues(count);
access.Push("hello", "world", 1, 2, 3);
count = await access.RunAsync(f);
results = access.ReadReturnValues(count);
for (int i = 0; i < results.Length; i++)
{
Console.WriteLine(results[i]);
Expand Down
2 changes: 1 addition & 1 deletion sandbox/JitTest/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

for (int i = 0; i < 1000; i++)
{
await luaState.MainThread.RunAsync(closure);
await luaState.TopLevelAccess.RunAsync(closure);
luaState.MainThread.Stack.Clear();
}

Expand Down
3 changes: 3 additions & 0 deletions src/Lua/InternalVisibleTo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Lua.Tests")]
5 changes: 2 additions & 3 deletions src/Lua/LuaCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ internal void Init(LuaThread parent, LuaFunction function, bool isProtectedMode)
State = parent.State;
IsProtectedMode = isProtectedMode;
Function = function;
IsRunning = false;
}

public override LuaThreadStatus GetStatus() => (LuaThreadStatus)status;
Expand Down Expand Up @@ -153,8 +152,8 @@ async ValueTask<int> ResumeAsyncCore(LuaStack stack, int argCount, int returnBas
if (isFirstCall)
{
Stack.PushRange(stack.AsSpan()[^argCount..]);
functionTask = Function.InvokeAsync(new() { Thread = this, ArgumentCount = Stack.Count, ReturnFrameBase = 0 }, cancellationToken);

//functionTask = Function.InvokeAsync(new() { Access = this.CurrentAccess, ArgumentCount = Stack.Count, ReturnFrameBase = 0 }, cancellationToken);
functionTask =CurrentAccess.RunAsync(Function,Stack.Count, cancellationToken);
Volatile.Write(ref isFirstCall, false);
if (!functionTask.IsCompleted)
{
Expand Down
29 changes: 0 additions & 29 deletions src/Lua/LuaFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,4 @@ public class LuaFunction(string name, Func<LuaFunctionExecutionContext, Cancella
public LuaFunction(Func<LuaFunctionExecutionContext, CancellationToken, ValueTask<int>> func) : this("anonymous", func)
{
}

public async ValueTask<int> InvokeAsync(LuaFunctionExecutionContext context, CancellationToken cancellationToken)
{
var varArgumentCount = this.GetVariableArgumentCount(context.ArgumentCount);
if (varArgumentCount != 0)
{
LuaVirtualMachine.PrepareVariableArgument(context.Thread.Stack, context.ArgumentCount, varArgumentCount);
context = context with { ArgumentCount = context.ArgumentCount - varArgumentCount };
}

var callStackFrameCount = context.Thread.CallStackFrameCount;
try
{
var frame = new CallStackFrame { Base = context.FrameBase, VariableArgumentCount = varArgumentCount, Function = this, ReturnBase = context.ReturnFrameBase };
context.Thread.PushCallStackFrame(frame);

if (context.Thread.CallOrReturnHookMask.Value != 0 && !context.Thread.IsInHook)
{
return await LuaVirtualMachine.ExecuteCallHook(context, cancellationToken);
}

var r = await Func(context, cancellationToken);
return r;
}
finally
{
context.Thread.PopCallStackFrameUntil(callStackFrameCount);
}
}
}
3 changes: 2 additions & 1 deletion src/Lua/LuaFunctionExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ namespace Lua;
public readonly record struct LuaFunctionExecutionContext
{
public LuaState State => Thread.State;
public required LuaThread Thread { get; init; }
public required LuaThreadAccess Access { get; init; }
public LuaThread Thread => Access.Thread;
public required int ArgumentCount { get; init; }
public int FrameBase => Thread.Stack.Count - ArgumentCount;
public required int ReturnFrameBase { get; init; }
Expand Down
84 changes: 43 additions & 41 deletions src/Lua/LuaFunctionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
using Lua.Runtime;

namespace Lua;

public static class LuaFunctionExtensions
{
public static async ValueTask<int> InvokeAsync(this LuaFunction function, LuaThread thread, int argumentCount, CancellationToken cancellationToken = default)
{
var varArgumentCount = function.GetVariableArgumentCount(argumentCount);
if (varArgumentCount != 0)
{
if (varArgumentCount < 0)
{
thread.Stack.SetTop(thread.Stack.Count - varArgumentCount);
argumentCount -= varArgumentCount;
varArgumentCount = 0;
}
else
{
LuaVirtualMachine.PrepareVariableArgument(thread.Stack, argumentCount, varArgumentCount);
}
}

LuaFunctionExecutionContext context = new() { Thread = thread, ArgumentCount = argumentCount - varArgumentCount, ReturnFrameBase = thread.Stack.Count, };
var frame = new CallStackFrame { Base = context.FrameBase, VariableArgumentCount = varArgumentCount, Function = function, ReturnBase = context.ReturnFrameBase };
context.Thread.PushCallStackFrame(frame);
try
{
if (context.Thread.CallOrReturnHookMask.Value != 0 && !context.Thread.IsInHook)
{
return await LuaVirtualMachine.ExecuteCallHook(context, cancellationToken);
}

return await function.Func(context, cancellationToken);
}
finally
{
context.Thread.PopCallStackFrame();
}
}
}
// using Lua.Runtime;
//
// namespace Lua;
//
// public static class LuaFunctionExtensions
// {
//
// public static async ValueTask<int> InvokeAsync(this LuaFunction function, LuaThread thread, int argumentCount, CancellationToken cancellationToken = default)
// {
// var returnFrameBase = thread.Stack.Count-argumentCount;
// var varArgumentCount = function.GetVariableArgumentCount(argumentCount);
// if (varArgumentCount != 0)
// {
// if (varArgumentCount < 0)
// {
// thread.Stack.SetTop(thread.Stack.Count - varArgumentCount);
// argumentCount -= varArgumentCount;
// varArgumentCount = 0;
// }
// else
// {
// LuaVirtualMachine.PrepareVariableArgument(thread.Stack, argumentCount, varArgumentCount);
// }
// }
//
// LuaFunctionExecutionContext context = new() { Thread = thread, ArgumentCount = argumentCount , ReturnFrameBase = returnFrameBase, };
// var frame = new CallStackFrame { Base = context.FrameBase, VariableArgumentCount = varArgumentCount, Function = function, ReturnBase = context.ReturnFrameBase };
// context.Thread.PushCallStackFrame(frame);
// try
// {
// if (context.Thread.CallOrReturnHookMask.Value != 0 && !context.Thread.IsInHook)
// {
// return await LuaVirtualMachine.ExecuteCallHook(context, cancellationToken);
// }
//
// return await function.Func(context, cancellationToken);
// }
// finally
// {
// context.Thread.PopCallStackFrame();
// }
// }
// }
2 changes: 2 additions & 0 deletions src/Lua/LuaState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public sealed class LuaState
public LuaTable LoadedModules => packages;
public LuaMainThread MainThread => mainThread;

public LuaThreadAccess TopLevelAccess => new (mainThread, 0);

public ILuaModuleLoader ModuleLoader { get; set; } = FileModuleLoader.Instance;

// metatables
Expand Down
10 changes: 6 additions & 4 deletions src/Lua/LuaStateExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
using Lua.Runtime;

namespace Lua;

public static class LuaStateExtensions
{
public static ValueTask<int> DoStringAsync(this LuaState state, string source, Memory<LuaValue> buffer, string? chunkName = null, CancellationToken cancellationToken = default)
{
return state.MainThread.DoStringAsync(source, buffer, chunkName, cancellationToken);
return state.TopLevelAccess.DoStringAsync(source, buffer, chunkName, cancellationToken);
}

public static ValueTask<LuaValue[]> DoStringAsync(this LuaState state, string source, string? chunkName = null, CancellationToken cancellationToken = default)
{
return state.MainThread.DoStringAsync(source, chunkName, cancellationToken);
return state.TopLevelAccess.DoStringAsync(source, chunkName, cancellationToken);
}

public static ValueTask<int> DoFileAsync(this LuaState state, string path, Memory<LuaValue> buffer, CancellationToken cancellationToken = default)
{
return state.MainThread.DoFileAsync(path, buffer, cancellationToken);
return state.TopLevelAccess.DoFileAsync(path, buffer, cancellationToken);
}

public static ValueTask<LuaValue[]> DoFileAsync(this LuaState state, string path, CancellationToken cancellationToken = default)
{
return state.MainThread.DoFileAsync(path, cancellationToken);
return state.TopLevelAccess.DoFileAsync(path, cancellationToken);
}
}
Loading