|
@@ -6,7 +6,7 @@ namespace Lua;
|
|
|
|
|
|
|
|
public abstract class LuaThread
|
|
public abstract class LuaThread
|
|
|
{
|
|
{
|
|
|
- internal LuaThread() { }
|
|
|
|
|
|
|
+ protected LuaThread() { }
|
|
|
|
|
|
|
|
public virtual LuaThreadStatus GetStatus()
|
|
public virtual LuaThreadStatus GetStatus()
|
|
|
{
|
|
{
|
|
@@ -25,11 +25,12 @@ public abstract class LuaThread
|
|
|
throw new LuaRuntimeException(context.Thread.GetTraceback(), "attempt to yield from outside a coroutine");
|
|
throw new LuaRuntimeException(context.Thread.GetTraceback(), "attempt to yield from outside a coroutine");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- internal class ThreadCoreData: IPoolNode<ThreadCoreData>
|
|
|
|
|
|
|
+ internal class ThreadCoreData : IPoolNode<ThreadCoreData>
|
|
|
{
|
|
{
|
|
|
//internal LuaCoroutineData? coroutineData;
|
|
//internal LuaCoroutineData? coroutineData;
|
|
|
internal LuaStack Stack = new();
|
|
internal LuaStack Stack = new();
|
|
|
internal FastStackCore<CallStackFrame> CallStack;
|
|
internal FastStackCore<CallStackFrame> CallStack;
|
|
|
|
|
+
|
|
|
public void Clear()
|
|
public void Clear()
|
|
|
{
|
|
{
|
|
|
Stack.Clear();
|
|
Stack.Clear();
|
|
@@ -39,7 +40,7 @@ public abstract class LuaThread
|
|
|
static LinkedPool<ThreadCoreData> pool;
|
|
static LinkedPool<ThreadCoreData> pool;
|
|
|
ThreadCoreData? nextNode;
|
|
ThreadCoreData? nextNode;
|
|
|
public ref ThreadCoreData? NextNode => ref nextNode;
|
|
public ref ThreadCoreData? NextNode => ref nextNode;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
public static ThreadCoreData Create()
|
|
public static ThreadCoreData Create()
|
|
|
{
|
|
{
|
|
|
if (!pool.TryPop(out ThreadCoreData result))
|
|
if (!pool.TryPop(out ThreadCoreData result))
|
|
@@ -56,19 +57,18 @@ public abstract class LuaThread
|
|
|
pool.TryPush(this);
|
|
pool.TryPush(this);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- public LuaState State { get;protected set; }
|
|
|
|
|
|
|
|
|
|
|
|
+ public LuaState State { get; protected set; } = null!;
|
|
|
internal ThreadCoreData? CoreData = new();
|
|
internal ThreadCoreData? CoreData = new();
|
|
|
-
|
|
|
|
|
internal BitFlags2 LineAndCountHookMask;
|
|
internal BitFlags2 LineAndCountHookMask;
|
|
|
internal BitFlags2 CallOrReturnHookMask;
|
|
internal BitFlags2 CallOrReturnHookMask;
|
|
|
internal bool IsInHook;
|
|
internal bool IsInHook;
|
|
|
internal int HookCount;
|
|
internal int HookCount;
|
|
|
internal int BaseHookCount;
|
|
internal int BaseHookCount;
|
|
|
internal int LastPc;
|
|
internal int LastPc;
|
|
|
|
|
+ public bool IsRunning { get; protected set; }
|
|
|
internal LuaFunction? Hook { get; set; }
|
|
internal LuaFunction? Hook { get; set; }
|
|
|
-
|
|
|
|
|
- internal LuaStack Stack => CoreData!.Stack;
|
|
|
|
|
|
|
+ public LuaStack Stack => CoreData!.Stack;
|
|
|
internal ref FastStackCore<CallStackFrame> CallStack => ref CoreData!.CallStack;
|
|
internal ref FastStackCore<CallStackFrame> CallStack => ref CoreData!.CallStack;
|
|
|
|
|
|
|
|
internal bool IsLineHookEnabled
|
|
internal bool IsLineHookEnabled
|
|
@@ -96,102 +96,41 @@ public abstract class LuaThread
|
|
|
set => CallOrReturnHookMask.Flag1 = value;
|
|
set => CallOrReturnHookMask.Flag1 = value;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- public void Push(LuaValue value)
|
|
|
|
|
- {
|
|
|
|
|
- CoreData.Stack.Push(value);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void Push(params ReadOnlySpan<LuaValue> span)
|
|
|
|
|
- {
|
|
|
|
|
- CoreData.Stack.PushRange(span);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public void Pop(int count)
|
|
|
|
|
- {
|
|
|
|
|
- CoreData.Stack.Pop(count);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public LuaValue Pop()
|
|
|
|
|
- {
|
|
|
|
|
- return CoreData.Stack.Pop();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- public ref readonly CallStackFrame GetCurrentFrame()
|
|
|
|
|
- {
|
|
|
|
|
- return ref CoreData.CallStack.PeekRef();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public ReadOnlySpan<LuaValue> GetStackValues()
|
|
|
|
|
- {
|
|
|
|
|
- return CoreData.Stack.AsSpan();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- public ReadOnlySpan<CallStackFrame> GetCallStackFrames()
|
|
|
|
|
- {
|
|
|
|
|
- return CoreData.CallStack.AsSpan();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
- internal void PushCallStackFrame(in CallStackFrame frame)
|
|
|
|
|
|
|
+ public async ValueTask<int> RunAsync(LuaClosure closure, CancellationToken cancellationToken = default)
|
|
|
{
|
|
{
|
|
|
- CoreData.CallStack.Push(frame);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ ThrowIfRunning();
|
|
|
|
|
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
- internal void PopCallStackFrameWithStackPop()
|
|
|
|
|
- {
|
|
|
|
|
- if (CoreData.CallStack.TryPop(out var frame))
|
|
|
|
|
|
|
+ IsRunning = true;
|
|
|
|
|
+ try
|
|
|
{
|
|
{
|
|
|
- CoreData.Stack.PopUntil(frame.Base);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- ThrowForEmptyStack();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ await closure.InvokeAsync(new()
|
|
|
|
|
+ {
|
|
|
|
|
+ Thread = this, ArgumentCount = 0, ReturnFrameBase = 0, SourceLine = null,
|
|
|
|
|
+ }, cancellationToken);
|
|
|
|
|
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
- internal void PopCallStackFrameWithStackPop(int frameBase)
|
|
|
|
|
- {
|
|
|
|
|
- if (CoreData.CallStack.TryPop())
|
|
|
|
|
- {
|
|
|
|
|
- CoreData.Stack.PopUntil(frameBase);
|
|
|
|
|
|
|
+ return Stack.Count;
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
|
|
+ finally
|
|
|
{
|
|
{
|
|
|
- ThrowForEmptyStack();
|
|
|
|
|
|
|
+ IsRunning = false;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
- internal void PopCallStackFrame()
|
|
|
|
|
- {
|
|
|
|
|
- if (!CoreData.CallStack.TryPop())
|
|
|
|
|
- {
|
|
|
|
|
- ThrowForEmptyStack();
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
internal void DumpStackValues()
|
|
internal void DumpStackValues()
|
|
|
{
|
|
{
|
|
|
- var span = GetStackValues();
|
|
|
|
|
|
|
+ var span = this.GetStackValues();
|
|
|
for (int i = 0; i < span.Length; i++)
|
|
for (int i = 0; i < span.Length; i++)
|
|
|
{
|
|
{
|
|
|
Console.WriteLine($"LuaStack [{i}]\t{span[i]}");
|
|
Console.WriteLine($"LuaStack [{i}]\t{span[i]}");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public Traceback GetTraceback()
|
|
|
|
|
|
|
+ protected void ThrowIfRunning()
|
|
|
{
|
|
{
|
|
|
- var frames = GetCallStackFrames();
|
|
|
|
|
-
|
|
|
|
|
- return new(State) { RootFunc = frames[0].Function, StackFrames = GetCallStackFrames()[1..].ToArray() };
|
|
|
|
|
|
|
+ if (IsRunning)
|
|
|
|
|
+ {
|
|
|
|
|
+ throw new InvalidOperationException("the lua state is currently running");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- static void ThrowForEmptyStack() => throw new InvalidOperationException("Empty stack");
|
|
|
|
|
}
|
|
}
|