|
|
@@ -130,7 +130,7 @@ public class FunctionCompilationContext : IDisposable
|
|
|
/// Push or merge the new instruction.
|
|
|
/// </summary>
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in SourcePosition position, ref bool incrementStackPosition)
|
|
|
+ public void PushOrMergeInstruction(in Instruction instruction, in SourcePosition position, ref bool incrementStackPosition)
|
|
|
{
|
|
|
if (instructions.Length == 0)
|
|
|
{
|
|
|
@@ -139,27 +139,40 @@ public class FunctionCompilationContext : IDisposable
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+ var activeLocals = Scope.ActiveLocalVariables;
|
|
|
+
|
|
|
ref var lastInstruction = ref instructions.AsSpan()[^1];
|
|
|
var opcode = instruction.OpCode;
|
|
|
switch (opcode)
|
|
|
{
|
|
|
case OpCode.Move:
|
|
|
- // last A is not local variable
|
|
|
- if (lastInstruction.A != lastLocal &&
|
|
|
- // available to merge
|
|
|
- lastInstruction.A == instruction.B &&
|
|
|
- // not already merged
|
|
|
- lastInstruction.A != lastInstruction.B)
|
|
|
+
|
|
|
+ if (
|
|
|
+ // available to merge and last A is not local variable
|
|
|
+ lastInstruction.A == instruction.B && !activeLocals[lastInstruction.A])
|
|
|
{
|
|
|
switch (lastInstruction.OpCode)
|
|
|
{
|
|
|
- case OpCode.GetTable:
|
|
|
+ case OpCode.LoadK:
|
|
|
+ case OpCode.LoadBool when lastInstruction.C == 0:
|
|
|
+ case OpCode.LoadNil when lastInstruction.B == 0:
|
|
|
+ case OpCode.GetUpVal:
|
|
|
+ case OpCode.GetTabUp:
|
|
|
+ case OpCode.GetTable when !activeLocals[lastInstruction.B]:
|
|
|
+ case OpCode.SetTabUp:
|
|
|
+ case OpCode.SetUpVal:
|
|
|
+ case OpCode.SetTable:
|
|
|
+ case OpCode.NewTable:
|
|
|
+ case OpCode.Self:
|
|
|
case OpCode.Add:
|
|
|
case OpCode.Sub:
|
|
|
case OpCode.Mul:
|
|
|
case OpCode.Div:
|
|
|
case OpCode.Mod:
|
|
|
case OpCode.Pow:
|
|
|
+ case OpCode.Unm:
|
|
|
+ case OpCode.Not:
|
|
|
+ case OpCode.Len:
|
|
|
case OpCode.Concat:
|
|
|
{
|
|
|
lastInstruction.A = instruction.A;
|
|
|
@@ -173,7 +186,7 @@ public class FunctionCompilationContext : IDisposable
|
|
|
case OpCode.GetTable:
|
|
|
{
|
|
|
// Merge MOVE GetTable
|
|
|
- if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A)
|
|
|
+ if (lastInstruction.OpCode == OpCode.Move && !activeLocals[lastInstruction.A])
|
|
|
{
|
|
|
if (lastInstruction.A == instruction.B)
|
|
|
{
|
|
|
@@ -189,7 +202,7 @@ public class FunctionCompilationContext : IDisposable
|
|
|
case OpCode.SetTable:
|
|
|
{
|
|
|
// Merge MOVE SETTABLE
|
|
|
- if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A)
|
|
|
+ if (lastInstruction.OpCode == OpCode.Move && !activeLocals[lastInstruction.A])
|
|
|
{
|
|
|
var lastB = lastInstruction.B;
|
|
|
var lastA = lastInstruction.A;
|
|
|
@@ -200,7 +213,7 @@ public class FunctionCompilationContext : IDisposable
|
|
|
{
|
|
|
ref var last2Instruction = ref instructions.AsSpan()[^2];
|
|
|
var last2A = last2Instruction.A;
|
|
|
- if (last2Instruction.OpCode == OpCode.Move && lastLocal != last2A && instruction.C == last2A)
|
|
|
+ if (last2Instruction.OpCode == OpCode.Move && !activeLocals[last2A] && instruction.C == last2A)
|
|
|
{
|
|
|
last2Instruction = Instruction.SetTable((byte)(lastB), instruction.B, last2Instruction.B);
|
|
|
instructions.RemoveAtSwapback(instructions.Length - 1);
|
|
|
@@ -232,7 +245,7 @@ public class FunctionCompilationContext : IDisposable
|
|
|
if (last2OpCode is OpCode.LoadK or OpCode.Move)
|
|
|
{
|
|
|
var last2A = last2Instruction.A;
|
|
|
- if (last2A != lastLocal && instruction.C == last2A)
|
|
|
+ if (!activeLocals[last2A] && instruction.C == last2A)
|
|
|
{
|
|
|
var c = last2OpCode == OpCode.LoadK ? last2Instruction.Bx + 256 : last2Instruction.B;
|
|
|
last2Instruction = lastInstruction;
|
|
|
@@ -250,10 +263,9 @@ public class FunctionCompilationContext : IDisposable
|
|
|
case OpCode.Unm:
|
|
|
case OpCode.Not:
|
|
|
case OpCode.Len:
|
|
|
- if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A && lastInstruction.A == instruction.B)
|
|
|
+ if (lastInstruction.OpCode == OpCode.Move && !activeLocals[lastInstruction.A] && lastInstruction.A == instruction.B)
|
|
|
{
|
|
|
lastInstruction = instruction with { B = lastInstruction.B };
|
|
|
- ;
|
|
|
instructionPositions[^1] = position;
|
|
|
incrementStackPosition = false;
|
|
|
return;
|
|
|
@@ -264,6 +276,7 @@ public class FunctionCompilationContext : IDisposable
|
|
|
if (lastInstruction.OpCode == OpCode.Move && instruction.B == 2 && lastInstruction.B < 256)
|
|
|
{
|
|
|
lastInstruction = instruction with { A = (byte)lastInstruction.B };
|
|
|
+
|
|
|
instructionPositions[^1] = position;
|
|
|
incrementStackPosition = false;
|
|
|
return;
|