|
|
@@ -215,10 +215,11 @@ public static partial class LuaVirtualMachine
|
|
|
State.PopCallStackFrameUntil(BaseCallStackCount);
|
|
|
}
|
|
|
|
|
|
- bool ExecutePostOperation(PostOperationType postOperation)
|
|
|
+ bool ExecutePostOperation(int varArgs, PostOperationType postOperation)
|
|
|
{
|
|
|
var stackCount = Stack.Count;
|
|
|
var resultsSpan = Stack.GetBuffer()[CurrentReturnFrameBase..];
|
|
|
+ var lastTop = CurrentReturnFrameBase - varArgs;
|
|
|
switch (postOperation)
|
|
|
{
|
|
|
case PostOperationType.Nop: break;
|
|
|
@@ -226,7 +227,7 @@ public static partial class LuaVirtualMachine
|
|
|
var RA = Instruction.A + FrameBase;
|
|
|
Stack.Get(RA) = stackCount > CurrentReturnFrameBase ? Stack.Get(CurrentReturnFrameBase) : LuaValue.Nil;
|
|
|
Stack.NotifyTop(RA + 1);
|
|
|
- Stack.PopUntil(RA + 1);
|
|
|
+ Stack.PopUntil(Math.Max(RA + 1, lastTop));
|
|
|
break;
|
|
|
case PostOperationType.TForCall:
|
|
|
TForCallPostOperation(this);
|
|
|
@@ -242,10 +243,10 @@ public static partial class LuaVirtualMachine
|
|
|
|
|
|
break;
|
|
|
case PostOperationType.Self:
|
|
|
- SelfPostOperation(this, resultsSpan);
|
|
|
+ SelfPostOperation(this, lastTop, resultsSpan);
|
|
|
break;
|
|
|
case PostOperationType.Compare:
|
|
|
- ComparePostOperation(this, resultsSpan);
|
|
|
+ ComparePostOperation(this, lastTop, resultsSpan);
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
@@ -263,12 +264,15 @@ public static partial class LuaVirtualMachine
|
|
|
toCatchFlag = true;
|
|
|
await Task;
|
|
|
Task = default;
|
|
|
+ ref readonly var frame = ref State.GetCurrentFrame();
|
|
|
+ CurrentReturnFrameBase = frame.ReturnBase;
|
|
|
+ var variableArgumentCount = frame.VariableArgumentCount;
|
|
|
if (PostOperation is not (PostOperationType.TailCall or PostOperationType.DontPop))
|
|
|
{
|
|
|
State.PopCallStackFrame();
|
|
|
}
|
|
|
|
|
|
- if (!ExecutePostOperation(PostOperation))
|
|
|
+ if (!ExecutePostOperation(variableArgumentCount, PostOperation))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
@@ -350,7 +354,7 @@ public static partial class LuaVirtualMachine
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
- // This is a label to restart the execution when new function is called or restarted
|
|
|
+ // This is a label to restart the execution when new function is called or restarted
|
|
|
Restart:
|
|
|
ref var instructionsHead = ref Unsafe.AsRef(in context.Prototype.Code[0]);
|
|
|
var frameBase = context.FrameBase;
|
|
|
@@ -411,6 +415,7 @@ public static partial class LuaVirtualMachine
|
|
|
{
|
|
|
context.Pc++;
|
|
|
}
|
|
|
+
|
|
|
continue;
|
|
|
case OpCode.LoadNil:
|
|
|
Markers.LoadNil();
|
|
|
@@ -957,7 +962,7 @@ public static partial class LuaVirtualMachine
|
|
|
return mod;
|
|
|
}
|
|
|
|
|
|
- static void SelfPostOperation(VirtualMachineExecutionContext context, Span<LuaValue> results)
|
|
|
+ static void SelfPostOperation(VirtualMachineExecutionContext context, int lastTop, Span<LuaValue> results)
|
|
|
{
|
|
|
var stack = context.Stack;
|
|
|
var instruction = context.Instruction;
|
|
|
@@ -967,6 +972,7 @@ public static partial class LuaVirtualMachine
|
|
|
var table = Unsafe.Add(ref stackHead, RB);
|
|
|
Unsafe.Add(ref stackHead, RA + 1) = table;
|
|
|
Unsafe.Add(ref stackHead, RA) = results.Length == 0 ? LuaValue.Nil : results[0];
|
|
|
+ stack.PopUntil(Math.Max(RA + 2, lastTop));
|
|
|
stack.NotifyTop(RA + 2);
|
|
|
}
|
|
|
|
|
|
@@ -1266,7 +1272,6 @@ public static partial class LuaVirtualMachine
|
|
|
if (!task.IsCompleted)
|
|
|
{
|
|
|
context.PostOperation = PostOperationType.Call;
|
|
|
- context.CurrentReturnFrameBase = returnBase;
|
|
|
context.Task = task;
|
|
|
return false;
|
|
|
}
|
|
|
@@ -1558,7 +1563,7 @@ public static partial class LuaVirtualMachine
|
|
|
stack.PopUntil(RA + 1);
|
|
|
}
|
|
|
|
|
|
- static void ComparePostOperation(VirtualMachineExecutionContext context, Span<LuaValue> results)
|
|
|
+ static void ComparePostOperation(VirtualMachineExecutionContext context, int lastTop, Span<LuaValue> results)
|
|
|
{
|
|
|
var compareResult = results.Length != 0 && results[0].ToBoolean();
|
|
|
if (compareResult != (context.Instruction.A == 1))
|
|
|
@@ -1567,6 +1572,7 @@ public static partial class LuaVirtualMachine
|
|
|
}
|
|
|
|
|
|
results.Clear();
|
|
|
+ context.Stack.PopUntil(lastTop);
|
|
|
}
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
@@ -2003,16 +2009,20 @@ public static partial class LuaVirtualMachine
|
|
|
if (!task.IsCompleted)
|
|
|
{
|
|
|
context.PostOperation = PostOperationType.SetResult;
|
|
|
- context.CurrentReturnFrameBase = newFrame.ReturnBase;
|
|
|
context.Task = task;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- stack.Get(context.Instruction.A + context.FrameBase)
|
|
|
- = task.GetAwaiter().GetResult() != 0
|
|
|
- ? stack.FastGet(newFrame.ReturnBase)
|
|
|
- : default;
|
|
|
- stack.PopUntil(newFrame.ReturnBase + 1);
|
|
|
+ var destIndex = context.Instruction.A + context.FrameBase;
|
|
|
+ if (newFrame.ReturnBase != destIndex)
|
|
|
+ {
|
|
|
+ stack.Get(destIndex)
|
|
|
+ = task.GetAwaiter().GetResult() != 0
|
|
|
+ ? stack.FastGet(newFrame.ReturnBase)
|
|
|
+ : default;
|
|
|
+ }
|
|
|
+
|
|
|
+ stack.PopUntil(Math.Max(destIndex + 1, newFrame.Base - newFrame.VariableArgumentCount));
|
|
|
context.State.PopCallStackFrame();
|
|
|
return true;
|
|
|
}
|
|
|
@@ -2131,16 +2141,20 @@ public static partial class LuaVirtualMachine
|
|
|
if (!task.IsCompleted)
|
|
|
{
|
|
|
context.PostOperation = PostOperationType.SetResult;
|
|
|
- context.CurrentReturnFrameBase = newFrame.ReturnBase;
|
|
|
context.Task = task;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- var result = stack.Count > newFrame.ReturnBase
|
|
|
- ? stack.Get(newFrame.ReturnBase)
|
|
|
- : default;
|
|
|
- stack.Get(context.Instruction.A + context.FrameBase) = result;
|
|
|
- stack.PopUntil(newFrame.ReturnBase + 1);
|
|
|
+ var destIndex = context.Instruction.A + context.FrameBase;
|
|
|
+ if (newFrame.ReturnBase != destIndex)
|
|
|
+ {
|
|
|
+ stack.Get(destIndex)
|
|
|
+ = task.GetAwaiter().GetResult() != 0
|
|
|
+ ? stack.FastGet(newFrame.ReturnBase)
|
|
|
+ : default;
|
|
|
+ }
|
|
|
+
|
|
|
+ stack.PopUntil(Math.Max(destIndex + 1, newFrame.Base - newFrame.VariableArgumentCount));
|
|
|
context.State.PopCallStackFrame();
|
|
|
return true;
|
|
|
}
|
|
|
@@ -2274,20 +2288,19 @@ public static partial class LuaVirtualMachine
|
|
|
if (!task.IsCompleted)
|
|
|
{
|
|
|
context.PostOperation = PostOperationType.Compare;
|
|
|
- context.CurrentReturnFrameBase = newFrame.ReturnBase;
|
|
|
context.Task = task;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
var results = stack.AsSpan()[newFrame.ReturnBase..];
|
|
|
- var compareResult = results.Length == 0 && results[0].ToBoolean();
|
|
|
+ var compareResult = results.Length > 0 && results[0].ToBoolean();
|
|
|
compareResult = reverseLe ? !compareResult : compareResult;
|
|
|
if (compareResult != (context.Instruction.A == 1))
|
|
|
{
|
|
|
context.Pc++;
|
|
|
}
|
|
|
|
|
|
- stack.PopUntil(newFrame.ReturnBase + 1);
|
|
|
+ stack.PopUntil(newFrame.Base - newFrame.VariableArgumentCount + 1);
|
|
|
context.State.PopCallStackFrame();
|
|
|
|
|
|
return true;
|