From ddf6d44bb0e9c1c31d1f77377f2a3a56e26c680a Mon Sep 17 00:00:00 2001 From: Akeit0 <90429982+Akeit0@users.noreply.github.com> Date: Mon, 4 Nov 2024 11:41:14 +0900 Subject: [PATCH 1/7] Optimize: Reduce and merge unnecessary move instructions --- .../Compilation/FunctionCompilationContext.cs | 78 +++++++++++++++++++ .../Compilation/ScopeCompilationContext.cs | 18 ++++- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs index bc59f04a..7836455b 100644 --- a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs @@ -110,6 +110,84 @@ public void PushInstruction(in Instruction instruction, in SourcePosition positi instructionPositions.Add(position); } + /// + /// Push or merge the new instruction. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PushOrMergeInstruction(in Instruction instruction, in SourcePosition position,ref bool incrementStackPosition) + { + if(instructions.Length==0) + { + instructions.Add(instruction); + instructionPositions.Add(position); + return; + } + ref var lastInstruction = ref instructions.AsSpan()[^1]; + var opcode = instruction.OpCode; + switch (opcode) + { + case OpCode.Move: + if (lastInstruction.A ==instruction.B) + { + switch (lastInstruction.OpCode) + { + case OpCode.GetTable: + case OpCode.Add: + case OpCode.Sub: + case OpCode.Mul: + case OpCode.Div: + case OpCode.Mod: + case OpCode.Pow: + { + lastInstruction.A = instruction.A; + incrementStackPosition = false; + return; + } + } + } + break; + case OpCode.GetTable: + { + if (lastInstruction.OpCode == OpCode.Move) + { + var b = instruction.B; + if (instruction.A==b&&lastInstruction.A == b) + { + lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C); + incrementStackPosition = false; + return; + } + } + break; + } + case OpCode.SetTable: + { + if (lastInstruction.OpCode == OpCode.Move) + { + var lastB = lastInstruction.B; + var lastA = lastInstruction.A; + if (lastB<255 && lastA == instruction.A) + { + lastInstruction=Instruction.SetTable((byte)(lastB), instruction.B, instruction.C); + incrementStackPosition = false; + return; + } + + if (lastA == instruction.C) + { + lastInstruction=Instruction.SetTable(instruction.A, instruction.B, instruction.C); + incrementStackPosition = false; + return; + } + } + break; + } + } + + instructions.Add(instruction); + instructionPositions.Add(position); + } + /// /// Gets the index of the constant from the value, or if the constant is not registered it is added and its index is returned. /// diff --git a/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs index bdf52129..659b4491 100644 --- a/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs @@ -33,6 +33,8 @@ public static void Return(ScopeCompilationContext context) readonly Dictionary, LocalVariableDescription> localVariables = new(256, Utf16StringMemoryComparer.Default); readonly Dictionary, LabelDescription> labels = new(32, Utf16StringMemoryComparer.Default); + byte lastLocalVariableIndex; + public byte StackStartPosition { get; private set; } public byte StackPosition { get; set; } @@ -72,8 +74,18 @@ public FunctionCompilationContext CreateChildFunction() [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PushInstruction(in Instruction instruction, SourcePosition position, bool incrementStackPosition = false) { - Function.PushInstruction(instruction, position); - if (incrementStackPosition) StackPosition++; + if (lastLocalVariableIndex == StackPosition - 1) + { + Function.PushInstruction(instruction, position); + } + else + { + Function.PushOrMergeInstruction(instruction, position, ref incrementStackPosition); + } + if(incrementStackPosition) + { + StackPosition++; + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -92,6 +104,7 @@ public void TryPushCloseUpValue(byte top, SourcePosition position) public void AddLocalVariable(ReadOnlyMemory name, LocalVariableDescription description) { localVariables[name] = description; + lastLocalVariableIndex = description.RegisterIndex; } /// @@ -157,6 +170,7 @@ public void Reset() HasCapturedLocalVariables = false; localVariables.Clear(); labels.Clear(); + lastLocalVariableIndex = 0; } /// From e15f0268d25beea2d068e9c0b0cc23e8d1066fd7 Mon Sep 17 00:00:00 2001 From: Akeit0 <90429982+Akeit0@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:29:06 +0900 Subject: [PATCH 2/7] Optimize: MOVE MOVE SETTABLE Pattern --- .../Compilation/FunctionCompilationContext.cs | 40 +++++++++++++------ .../Compilation/ScopeCompilationContext.cs | 12 ++---- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs index 7836455b..a1f96555 100644 --- a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs @@ -114,7 +114,7 @@ public void PushInstruction(in Instruction instruction, in SourcePosition positi /// Push or merge the new instruction. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PushOrMergeInstruction(in Instruction instruction, in SourcePosition position,ref bool incrementStackPosition) + public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in SourcePosition position,ref bool incrementStackPosition) { if(instructions.Length==0) { @@ -127,7 +127,7 @@ public void PushOrMergeInstruction(in Instruction instruction, in SourcePosition switch (opcode) { case OpCode.Move: - if (lastInstruction.A ==instruction.B) + if (lastInstruction.A!=lastLocal&&lastInstruction.A ==instruction.B) { switch (lastInstruction.OpCode) { @@ -148,26 +148,42 @@ public void PushOrMergeInstruction(in Instruction instruction, in SourcePosition break; case OpCode.GetTable: { - if (lastInstruction.OpCode == OpCode.Move) + //Merge MOVE GetTable + if (lastInstruction.OpCode == OpCode.Move&&lastLocal != lastInstruction.A) { - var b = instruction.B; - if (instruction.A==b&&lastInstruction.A == b) - { - lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C); - incrementStackPosition = false; - return; - } + var b = instruction.B; + if (instruction.A==b&&lastInstruction.A == b) + { + lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C); + incrementStackPosition = false; + return; + } + } break; } case OpCode.SetTable: { - if (lastInstruction.OpCode == OpCode.Move) + //Merge MOVE SETTABLE + if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A) { var lastB = lastInstruction.B; var lastA = lastInstruction.A; if (lastB<255 && lastA == instruction.A) { + //Merge MOVE MOVE SETTABLE + if (instructions.Length > 2) + { + ref var last2Instruction = ref instructions.AsSpan()[^2]; + var last2A = last2Instruction.A; + if(last2Instruction.OpCode == OpCode.Move && lastLocal != last2A && instruction.C == last2A) + { + last2Instruction=Instruction.SetTable((byte)(lastB), instruction.B, last2Instruction.B); + instructions.RemoveAtSwapback(instructions.Length - 1); + incrementStackPosition = false; + return; + } + } lastInstruction=Instruction.SetTable((byte)(lastB), instruction.B, instruction.C); incrementStackPosition = false; return; @@ -175,7 +191,7 @@ public void PushOrMergeInstruction(in Instruction instruction, in SourcePosition if (lastA == instruction.C) { - lastInstruction=Instruction.SetTable(instruction.A, instruction.B, instruction.C); + lastInstruction=Instruction.SetTable(instruction.A, instruction.B, lastB); incrementStackPosition = false; return; } diff --git a/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs index 659b4491..eb9c215a 100644 --- a/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs @@ -74,14 +74,7 @@ public FunctionCompilationContext CreateChildFunction() [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PushInstruction(in Instruction instruction, SourcePosition position, bool incrementStackPosition = false) { - if (lastLocalVariableIndex == StackPosition - 1) - { - Function.PushInstruction(instruction, position); - } - else - { - Function.PushOrMergeInstruction(instruction, position, ref incrementStackPosition); - } + Function.PushOrMergeInstruction(lastLocalVariableIndex,instruction, position, ref incrementStackPosition); if(incrementStackPosition) { StackPosition++; @@ -101,11 +94,12 @@ public void TryPushCloseUpValue(byte top, SourcePosition position) /// Add new local variable. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AddLocalVariable(ReadOnlyMemory name, LocalVariableDescription description) + public void AddLocalVariable(ReadOnlyMemory name, LocalVariableDescription description,bool markAsLastLocalVariable = true) { localVariables[name] = description; lastLocalVariableIndex = description.RegisterIndex; } + /// /// Gets the local variable in scope. From f9862f0b5ad810da494c7f0795361a7120521f98 Mon Sep 17 00:00:00 2001 From: Akeit0 <90429982+Akeit0@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:45:19 +0900 Subject: [PATCH 3/7] Optimize: MOVE Unm Pattern --- .../Compilation/FunctionCompilationContext.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs index a1f96555..92259dce 100644 --- a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs @@ -198,6 +198,17 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in } break; } + case OpCode.Unm: + if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A) + { + if (lastInstruction.A == instruction.B) + { + lastInstruction=Instruction.Unm(instruction.A, lastInstruction.B); + incrementStackPosition = false; + return; + } + } + break; } instructions.Add(instruction); From b1fb869a04062d6d3d45739a951c70d6fc420adb Mon Sep 17 00:00:00 2001 From: Akeit0 <90429982+Akeit0@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:56:26 +0900 Subject: [PATCH 4/7] Optimize: Merge more instructions --- .../Compilation/FunctionCompilationContext.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs index 92259dce..8292c2b8 100644 --- a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs @@ -138,6 +138,7 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in case OpCode.Div: case OpCode.Mod: case OpCode.Pow: + case OpCode.Concat: { lastInstruction.A = instruction.A; incrementStackPosition = false; @@ -199,14 +200,13 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in break; } case OpCode.Unm: - if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A) + case OpCode.Not: + case OpCode.Len: + if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A && lastInstruction.A == instruction.B) { - if (lastInstruction.A == instruction.B) - { - lastInstruction=Instruction.Unm(instruction.A, lastInstruction.B); - incrementStackPosition = false; - return; - } + lastInstruction = instruction with { B = lastInstruction.B };; + incrementStackPosition = false; + return; } break; } From a3bf5df47ad720b950cf05e151c048b1403fb00d Mon Sep 17 00:00:00 2001 From: Akeit0 <90429982+Akeit0@users.noreply.github.com> Date: Mon, 4 Nov 2024 16:16:26 +0900 Subject: [PATCH 5/7] Optimize: merge more patterns --- .../Compilation/FunctionCompilationContext.cs | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs index 8292c2b8..06590d84 100644 --- a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs @@ -127,7 +127,12 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in switch (opcode) { case OpCode.Move: - if (lastInstruction.A!=lastLocal&&lastInstruction.A ==instruction.B) + //last A is not local variable + if (lastInstruction.A!=lastLocal && + //available to merge + lastInstruction.A == instruction.B && + //not already merged + lastInstruction.A != lastInstruction.B) { switch (lastInstruction.OpCode) { @@ -150,15 +155,14 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in case OpCode.GetTable: { //Merge MOVE GetTable - if (lastInstruction.OpCode == OpCode.Move&&lastLocal != lastInstruction.A) + if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A) { - var b = instruction.B; - if (instruction.A==b&&lastInstruction.A == b) - { - lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C); - incrementStackPosition = false; - return; - } + if (lastInstruction.A == instruction.B) + { + lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C); + incrementStackPosition = false; + return; + } } break; @@ -181,6 +185,7 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in { last2Instruction=Instruction.SetTable((byte)(lastB), instruction.B, last2Instruction.B); instructions.RemoveAtSwapback(instructions.Length - 1); + instructionPositions.RemoveAtSwapback(instructionPositions.Length - 1); incrementStackPosition = false; return; } @@ -197,6 +202,24 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in return; } } + else if (lastInstruction.OpCode == OpCode.GetTabUp&&instructions.Length >= 2) + { + ref var last2Instruction = ref instructions[^2]; + var last2OpCode = last2Instruction.OpCode; + if (last2OpCode is OpCode.LoadK or OpCode.Move) + { + + var last2A = last2Instruction.A; + if (last2A != lastLocal && instruction.C == last2A) + { + var c = last2OpCode==OpCode.LoadK?last2Instruction.Bx+256:last2Instruction.B; + last2Instruction = lastInstruction; + lastInstruction = instruction with { C = (ushort)c}; + incrementStackPosition = false; + return; + } + } + } break; } case OpCode.Unm: @@ -209,6 +232,14 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in return; } break; + case OpCode.Return: + if (lastInstruction.OpCode == OpCode.Move && instruction.B ==2 && lastInstruction.B < 256) + { + lastInstruction = instruction with { A = (byte)lastInstruction.B }; + incrementStackPosition = false; + return; + } + break; } instructions.Add(instruction); From 466b2acec052daffc00a220eae4551e53d2b2c7f Mon Sep 17 00:00:00 2001 From: Akeit0 <90429982+Akeit0@users.noreply.github.com> Date: Tue, 5 Nov 2024 09:01:01 +0900 Subject: [PATCH 6/7] Fix: fix SourcePositions on merge instructions --- .../Compilation/FunctionCompilationContext.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs index 06590d84..35edb07a 100644 --- a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs @@ -160,6 +160,7 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in if (lastInstruction.A == instruction.B) { lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C); + instructionPositions[^1] = position; incrementStackPosition = false; return; } @@ -186,11 +187,13 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in last2Instruction=Instruction.SetTable((byte)(lastB), instruction.B, last2Instruction.B); instructions.RemoveAtSwapback(instructions.Length - 1); instructionPositions.RemoveAtSwapback(instructionPositions.Length - 1); + instructionPositions[^1] = position; incrementStackPosition = false; return; } } lastInstruction=Instruction.SetTable((byte)(lastB), instruction.B, instruction.C); + instructionPositions[^1] = position; incrementStackPosition = false; return; } @@ -198,6 +201,7 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in if (lastA == instruction.C) { lastInstruction=Instruction.SetTable(instruction.A, instruction.B, lastB); + instructionPositions[^1] = position; incrementStackPosition = false; return; } @@ -215,6 +219,8 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in var c = last2OpCode==OpCode.LoadK?last2Instruction.Bx+256:last2Instruction.B; last2Instruction = lastInstruction; lastInstruction = instruction with { C = (ushort)c}; + instructionPositions[^2] = instructionPositions[^1]; + instructionPositions[^1] = position; incrementStackPosition = false; return; } @@ -228,6 +234,7 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A && lastInstruction.A == instruction.B) { lastInstruction = instruction with { B = lastInstruction.B };; + instructionPositions[^1] = position; incrementStackPosition = false; return; } @@ -236,6 +243,7 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in if (lastInstruction.OpCode == OpCode.Move && instruction.B ==2 && lastInstruction.B < 256) { lastInstruction = instruction with { A = (byte)lastInstruction.B }; + instructionPositions[^1] = position; incrementStackPosition = false; return; } From bd5ce70333216226a26d566808a4d439e8edb7da Mon Sep 17 00:00:00 2001 From: AnnulusGames Date: Sun, 29 Dec 2024 17:53:01 +0900 Subject: [PATCH 7/7] Run formatter --- .../Compilation/FunctionCompilationContext.cs | 152 +++++++++--------- .../Compilation/ScopeCompilationContext.cs | 10 +- 2 files changed, 81 insertions(+), 81 deletions(-) diff --git a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs index 35edb07a..2409a8ec 100644 --- a/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs @@ -114,9 +114,9 @@ public void PushInstruction(in Instruction instruction, in SourcePosition positi /// Push or merge the new instruction. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in SourcePosition position,ref bool incrementStackPosition) + public void PushOrMergeInstruction(int lastLocal, in Instruction instruction, in SourcePosition position, ref bool incrementStackPosition) { - if(instructions.Length==0) + if (instructions.Length == 0) { instructions.Add(instruction); instructionPositions.Add(position); @@ -127,13 +127,13 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in 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) - { + // last A is not local variable + if (lastInstruction.A != lastLocal && + // available to merge + lastInstruction.A == instruction.B && + // not already merged + lastInstruction.A != lastInstruction.B) + { switch (lastInstruction.OpCode) { case OpCode.GetTable: @@ -144,103 +144,103 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in case OpCode.Mod: case OpCode.Pow: case OpCode.Concat: - { - lastInstruction.A = instruction.A; - incrementStackPosition = false; - return; - } + { + lastInstruction.A = instruction.A; + incrementStackPosition = false; + return; + } } - } - break; + } + break; case OpCode.GetTable: - { - //Merge MOVE GetTable - if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A) { - if (lastInstruction.A == instruction.B) + // Merge MOVE GetTable + if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A) { - lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C); - instructionPositions[^1] = position; - incrementStackPosition = false; - return; + if (lastInstruction.A == instruction.B) + { + lastInstruction = Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C); + instructionPositions[^1] = position; + incrementStackPosition = false; + return; + } + } - + break; } - break; - } case OpCode.SetTable: - { - //Merge MOVE SETTABLE - if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A) { - var lastB = lastInstruction.B; - var lastA = lastInstruction.A; - if (lastB<255 && lastA == instruction.A) + // Merge MOVE SETTABLE + if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A) { - //Merge MOVE MOVE SETTABLE - if (instructions.Length > 2) + var lastB = lastInstruction.B; + var lastA = lastInstruction.A; + if (lastB < 255 && lastA == instruction.A) { - ref var last2Instruction = ref instructions.AsSpan()[^2]; - var last2A = last2Instruction.A; - if(last2Instruction.OpCode == OpCode.Move && lastLocal != last2A && instruction.C == last2A) + // Merge MOVE MOVE SETTABLE + if (instructions.Length > 2) { - last2Instruction=Instruction.SetTable((byte)(lastB), instruction.B, last2Instruction.B); - instructions.RemoveAtSwapback(instructions.Length - 1); - instructionPositions.RemoveAtSwapback(instructionPositions.Length - 1); - instructionPositions[^1] = position; - incrementStackPosition = false; - return; + ref var last2Instruction = ref instructions.AsSpan()[^2]; + var last2A = last2Instruction.A; + if (last2Instruction.OpCode == OpCode.Move && lastLocal != last2A && instruction.C == last2A) + { + last2Instruction = Instruction.SetTable((byte)(lastB), instruction.B, last2Instruction.B); + instructions.RemoveAtSwapback(instructions.Length - 1); + instructionPositions.RemoveAtSwapback(instructionPositions.Length - 1); + instructionPositions[^1] = position; + incrementStackPosition = false; + return; + } } + lastInstruction = Instruction.SetTable((byte)(lastB), instruction.B, instruction.C); + instructionPositions[^1] = position; + incrementStackPosition = false; + return; } - lastInstruction=Instruction.SetTable((byte)(lastB), instruction.B, instruction.C); - instructionPositions[^1] = position; - incrementStackPosition = false; - return; - } - if (lastA == instruction.C) - { - lastInstruction=Instruction.SetTable(instruction.A, instruction.B, lastB); - instructionPositions[^1] = position; - incrementStackPosition = false; - return; - } - } - else if (lastInstruction.OpCode == OpCode.GetTabUp&&instructions.Length >= 2) - { - ref var last2Instruction = ref instructions[^2]; - var last2OpCode = last2Instruction.OpCode; - if (last2OpCode is OpCode.LoadK or OpCode.Move) - { - - var last2A = last2Instruction.A; - if (last2A != lastLocal && instruction.C == last2A) + if (lastA == instruction.C) { - var c = last2OpCode==OpCode.LoadK?last2Instruction.Bx+256:last2Instruction.B; - last2Instruction = lastInstruction; - lastInstruction = instruction with { C = (ushort)c}; - instructionPositions[^2] = instructionPositions[^1]; + lastInstruction = Instruction.SetTable(instruction.A, instruction.B, lastB); instructionPositions[^1] = position; incrementStackPosition = false; return; } } + else if (lastInstruction.OpCode == OpCode.GetTabUp && instructions.Length >= 2) + { + ref var last2Instruction = ref instructions[^2]; + var last2OpCode = last2Instruction.OpCode; + if (last2OpCode is OpCode.LoadK or OpCode.Move) + { + + var last2A = last2Instruction.A; + if (last2A != lastLocal && instruction.C == last2A) + { + var c = last2OpCode == OpCode.LoadK ? last2Instruction.Bx + 256 : last2Instruction.B; + last2Instruction = lastInstruction; + lastInstruction = instruction with { C = (ushort)c }; + instructionPositions[^2] = instructionPositions[^1]; + instructionPositions[^1] = position; + incrementStackPosition = false; + return; + } + } + } + break; } - break; - } case OpCode.Unm: case OpCode.Not: case OpCode.Len: if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A && lastInstruction.A == instruction.B) { - lastInstruction = instruction with { B = lastInstruction.B };; + lastInstruction = instruction with { B = lastInstruction.B }; ; instructionPositions[^1] = position; incrementStackPosition = false; return; } break; case OpCode.Return: - if (lastInstruction.OpCode == OpCode.Move && instruction.B ==2 && lastInstruction.B < 256) + if (lastInstruction.OpCode == OpCode.Move && instruction.B == 2 && lastInstruction.B < 256) { lastInstruction = instruction with { A = (byte)lastInstruction.B }; instructionPositions[^1] = position; @@ -249,11 +249,11 @@ public void PushOrMergeInstruction(int lastLocal,in Instruction instruction, in } break; } - + instructions.Add(instruction); instructionPositions.Add(position); } - + /// /// Gets the index of the constant from the value, or if the constant is not registered it is added and its index is returned. /// diff --git a/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs b/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs index eb9c215a..ca63854b 100644 --- a/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs +++ b/src/Lua/CodeAnalysis/Compilation/ScopeCompilationContext.cs @@ -34,7 +34,7 @@ public static void Return(ScopeCompilationContext context) readonly Dictionary, LabelDescription> labels = new(32, Utf16StringMemoryComparer.Default); byte lastLocalVariableIndex; - + public byte StackStartPosition { get; private set; } public byte StackPosition { get; set; } @@ -74,8 +74,8 @@ public FunctionCompilationContext CreateChildFunction() [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PushInstruction(in Instruction instruction, SourcePosition position, bool incrementStackPosition = false) { - Function.PushOrMergeInstruction(lastLocalVariableIndex,instruction, position, ref incrementStackPosition); - if(incrementStackPosition) + Function.PushOrMergeInstruction(lastLocalVariableIndex, instruction, position, ref incrementStackPosition); + if (incrementStackPosition) { StackPosition++; } @@ -94,12 +94,12 @@ public void TryPushCloseUpValue(byte top, SourcePosition position) /// Add new local variable. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AddLocalVariable(ReadOnlyMemory name, LocalVariableDescription description,bool markAsLastLocalVariable = true) + public void AddLocalVariable(ReadOnlyMemory name, LocalVariableDescription description, bool markAsLastLocalVariable = true) { localVariables[name] = description; lastLocalVariableIndex = description.RegisterIndex; } - + /// /// Gets the local variable in scope.