diff --git a/src/Neo.Compiler.MSIL/Optimizer/NefInstruction.cs b/src/Neo.Compiler.MSIL/Optimizer/NefInstruction.cs index 8e0551320..83d539fe0 100644 --- a/src/Neo.Compiler.MSIL/Optimizer/NefInstruction.cs +++ b/src/Neo.Compiler.MSIL/Optimizer/NefInstruction.cs @@ -78,10 +78,18 @@ public int GetAddressInData(int index) if (AddressSize == 0) throw new Exception("this data have not Addresses"); - byte[] buf = new byte[4]; - Array.Copy(Data, AddressSize * index, buf, 0, AddressSize); - var addr = BitConverter.ToInt32(buf, 0); - return addr; + switch (AddressSize) + { + // 1 byte is stored as signed byte + case 1: return (sbyte)Data[index]; + case 4: + { + byte[] buf = new byte[4]; + Array.Copy(Data, AddressSize * index, buf, 0, AddressSize); + return BitConverter.ToInt32(buf, 0); + } + default: throw new Exception("this data have not a valid address"); + } } public void SetAddressInData(int index, int addr) diff --git a/src/Neo.Compiler.MSIL/Optimizer/NefOptimizeTool.cs b/src/Neo.Compiler.MSIL/Optimizer/NefOptimizeTool.cs index 4d46d3d47..c3871a2ff 100644 --- a/src/Neo.Compiler.MSIL/Optimizer/NefOptimizeTool.cs +++ b/src/Neo.Compiler.MSIL/Optimizer/NefOptimizeTool.cs @@ -47,21 +47,33 @@ public static byte[] Optimize(byte[] script, params OptimizeParserType[] parserT optimizer.AddOptimizeParser(parser); } - //step01 Load - using (var ms = new MemoryStream(script)) - { - optimizer.LoadNef(ms); - } - //step02 doOptimize - optimizer.Optimize(); + bool optimized; - //step03 link - using (var ms = new MemoryStream()) + do { - optimizer.LinkNef(ms); - var bytes = ms.ToArray(); - return bytes; + //step01 Load + using (var ms = new MemoryStream(script)) + { + optimizer.LoadNef(ms); + } + //step02 doOptimize + optimizer.Optimize(); + + //step03 link + using (var ms = new MemoryStream()) + { + optimizer.LinkNef(ms); + var bytes = ms.ToArray(); + + optimized = bytes.Length < script.Length; + if (optimized) { script = bytes; } + } + + // Execute it while decrease the size } + while (optimized); + + return script; } } } diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NefOptimizer.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NefOptimizer.cs index eff5b734c..bcfa53a33 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NefOptimizer.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NefOptimizer.cs @@ -92,6 +92,28 @@ public void Test_Optimize_Recalculate_JMPNE_L() Test_Optimize_Recalculate_Positive_JMPX_L(VM.OpCode.JMPNE_L); } + [TestMethod] + public void Test_CombinedRules() + { + using (var scriptBefore = new ScriptBuilder()) + using (var scriptAfter = new ScriptBuilder()) + { + scriptBefore.Emit(VM.OpCode.PUSH1); + scriptBefore.Emit(VM.OpCode.NOP); + scriptBefore.Emit(VM.OpCode.PUSH0); + scriptBefore.Emit(VM.OpCode.NOP); + scriptBefore.Emit(VM.OpCode.EQUAL); + scriptBefore.Emit(VM.OpCode.PUSH0); + scriptBefore.Emit(VM.OpCode.EQUAL); + + var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), OptimizeParserType.DELETE_USELESS_EQUAL, OptimizeParserType.DELETE_NOP); + + scriptAfter.Emit(VM.OpCode.PUSH1); + + CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); + } + } + [TestMethod] public void Test_Optimize_Recalculate_BoolEqualTrue() {