public void Test_Optimize_StaticMath_ADD() { using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.ADD); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.Emit(VM.OpCode.PUSH2); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSHM1); scriptBefore.Emit(VM.OpCode.PUSH11); scriptBefore.Emit(VM.OpCode.ADD); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.Emit(VM.OpCode.PUSH10); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } }
public void Test_Optimize_Static_DROP() { using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH0); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.DROP); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.Emit(VM.OpCode.PUSH0); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSHNULL); scriptBefore.Emit(VM.OpCode.DROP); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.Emit(VM.OpCode.PUSH1); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } }
public void Test_Optimize_StaticMath_DEC() { using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH0); scriptBefore.Emit(VM.OpCode.DEC); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.EmitPush(-1); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.EmitPush(short.MaxValue + 1); scriptBefore.Emit(VM.OpCode.DEC); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.EmitPush(short.MaxValue); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } }
private void Test_Optimize_Recalculate_Negative_JMPX_L(VM.OpCode biGJumpOpCode) { var smallJumpOpCode = (VM.OpCode)(biGJumpOpCode - 1); using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(biGJumpOpCode, ToJumpLArg(9)); // ───┐ scriptBefore.Emit(VM.OpCode.PUSH1); // <┐ │ scriptBefore.Emit(VM.OpCode.RET); // │ │ scriptBefore.Emit(VM.OpCode.NOP); // │ │ scriptBefore.Emit(VM.OpCode.NOP); // │ │ scriptBefore.Emit(biGJumpOpCode, ToJumpLArg(-4)); // x<┘ using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(smallJumpOpCode, ToJumpArg(4)); // ───┐ scriptAfter.Emit(VM.OpCode.PUSH1); // <┐ │ scriptAfter.Emit(VM.OpCode.RET); // │ │ scriptAfter.Emit(smallJumpOpCode, ToJumpArg(-2)); // x<┘ var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_DEAD_CODE | OptimizeParserType.USE_SHORT_ADDRESS ); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Test_Optimize_Recalculate_BoolEqualFalse() { using (var scriptBefore = new ScriptBuilder()) using (var scriptAfter = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.NOP); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSH0); scriptBefore.Emit(VM.OpCode.EQUAL); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), OptimizeParserType.DELETE_USELESS_EQUAL); scriptAfter.Emit(VM.OpCode.NOP); scriptAfter.Emit(VM.OpCode.PUSH0); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } using (var scriptBefore = new ScriptBuilder()) using (var scriptAfter = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.NOP); scriptBefore.Emit(VM.OpCode.PUSH0); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.EQUAL); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), OptimizeParserType.DELETE_USELESS_EQUAL); scriptAfter.Emit(VM.OpCode.NOP); scriptAfter.Emit(VM.OpCode.PUSH0); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } }
public void Test_Optimize_StaticMath_MUL() { using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSH2); scriptBefore.Emit(VM.OpCode.MUL); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.Emit(VM.OpCode.PUSH2); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.EmitPush(int.MaxValue); scriptBefore.EmitPush(int.MaxValue); scriptBefore.Emit(VM.OpCode.MUL); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.EmitPush(BigInteger.Multiply(new BigInteger(int.MaxValue), new BigInteger(int.MaxValue))); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } }
public void Test_Optimize_Delete_Dead_Code() { using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.NOP); scriptBefore.Emit(VM.OpCode.JMP, ToJumpArg(8)); // ─────┐ scriptBefore.Emit(VM.OpCode.PUSH1); // | scriptBefore.Emit(VM.OpCode.PUSH2); // | scriptBefore.Emit(VM.OpCode.PUSH3); // ┌<┐ | scriptBefore.Emit(VM.OpCode.JMP, ToJumpArg(6)); // x | | scriptBefore.Emit(VM.OpCode.PUSH4); // | | | scriptBefore.Emit(VM.OpCode.JMP, ToJumpArg(-4)); // | x<┘ scriptBefore.Emit(VM.OpCode.NOP); // | scriptBefore.Emit(VM.OpCode.PUSH5); // x<┘ scriptBefore.Emit(VM.OpCode.NOP); scriptBefore.Emit(VM.OpCode.PUSH6); scriptBefore.Emit(VM.OpCode.RET); scriptBefore.Emit(VM.OpCode.PUSH7); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_DEAD_CODE); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.JMP, ToJumpArg(5)); scriptAfter.Emit(VM.OpCode.PUSH3); scriptAfter.Emit(VM.OpCode.JMP, ToJumpArg(4)); scriptAfter.Emit(VM.OpCode.JMP, ToJumpArg(-3)); scriptAfter.Emit(VM.OpCode.PUSH5); scriptAfter.Emit(VM.OpCode.PUSH6); scriptAfter.Emit(VM.OpCode.RET); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.NOP); scriptBefore.Emit(VM.OpCode.JMP_L, ToJumpLArg(10)); // ───┐ scriptBefore.Emit(VM.OpCode.PUSH1); // | scriptBefore.Emit(VM.OpCode.PUSH2); // | scriptBefore.Emit(VM.OpCode.PUSH3); // x<┐ | scriptBefore.Emit(VM.OpCode.RET); // | | scriptBefore.Emit(VM.OpCode.PUSH4); // | | scriptBefore.Emit(VM.OpCode.JMP_L, ToJumpLArg(-3)); // x<┘ scriptBefore.Emit(VM.OpCode.PUSH5); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_DEAD_CODE); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.JMP_L, ToJumpLArg(7)); scriptAfter.Emit(VM.OpCode.PUSH3); scriptAfter.Emit(VM.OpCode.RET); scriptAfter.Emit(VM.OpCode.JMP_L, ToJumpLArg(-2)); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } }
public void Build(Stream fs, Stream fspdb, bool optimizer) { this.IsBuild = false; this.Error = null; var log = new DefLogger(); this.modIL = new ILModule(log); try { modIL.LoadModule(fs, fspdb); } catch (Exception err) { log.Log("LoadModule Error:" + err.ToString()); this.Error = err; return; } converterIL = new ModuleConverter(log); ConvOption option = new ConvOption(); #if NDEBUG try #endif { converterIL.Convert(modIL, option); finalNEF = converterIL.outModule.Build(); if (optimizer) { var opbytes = NefOptimizeTool.Optimize(finalNEF); float ratio = (opbytes.Length * 100.0f) / (float)finalNEF.Length; log.Log("optimization ratio = " + ratio + "%"); finalNEF = opbytes; } IsBuild = true; } #if NDEBUG catch (Exception err) { this.Error = err; log.Log("Convert IL->ASM Error:" + err.ToString()); return; } #endif try { finialABI = vmtool.FuncExport.Export(converterIL.outModule, finalNEF); } catch { } }
public void Test_Optimize_RemoveNOPS() { using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.NOP); scriptBefore.Emit(VM.OpCode.NOP); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray()); using var scriptAfter = new ScriptBuilder(); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Test_Optimize_ConstExecution_ROT() { using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSH2); scriptBefore.Emit(VM.OpCode.PUSH3); scriptBefore.Emit(VM.OpCode.ROT); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.Emit(VM.OpCode.PUSH2); scriptAfter.Emit(VM.OpCode.PUSH3); scriptAfter.Emit(VM.OpCode.PUSH1); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSH2); scriptBefore.Emit(VM.OpCode.PUSHNULL); scriptBefore.Emit(VM.OpCode.ROT); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.Emit(VM.OpCode.PUSH2); scriptAfter.Emit(VM.OpCode.PUSHNULL); scriptAfter.Emit(VM.OpCode.PUSH1); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH5); scriptBefore.Emit(VM.OpCode.PUSH4); scriptBefore.EmitJump(VM.OpCode.JMP, 3); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSH2); scriptBefore.Emit(VM.OpCode.PUSH3); scriptBefore.Emit(VM.OpCode.ROT); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptBefore.ToArray(), optimized); } }
public void Test_Optimize_JMP_Next() { using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.JMP, ToJumpArg(2)); // ───┐ scriptBefore.Emit(VM.OpCode.PUSH1); // <──┘ var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), new OptimizeParserType[] { OptimizeParserType.DELETE_USERLESS_JMP }); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.PUSH1); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Test_Optimize_RemoveNOPS() { using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.NOP); scriptBefore.Emit(VM.OpCode.NOP); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_DEAD_CODE | OptimizeParserType.USE_SHORT_ADDRESS ); using var scriptAfter = new ScriptBuilder(); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Test_Optimize_Recalculate_BoolNotEqualTrue() { using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.NOTEQUAL); scriptBefore.Emit(VM.OpCode.NOP); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.PUSH0); scriptAfter.Emit(VM.OpCode.NOP); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_USELESS_EQUAL); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Test_Optimize_Recalculate_Positive_PUSHA() { using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.PUSHA, ToJumpLArg(7)); // ─┐ scriptBefore.Emit(VM.OpCode.NOP); // │ scriptBefore.Emit(VM.OpCode.NOP); // │ scriptBefore.Emit(VM.OpCode.RET); // <┘ var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray()); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.PUSHA, ToJumpLArg(5)); // ─┐ scriptAfter.Emit(VM.OpCode.RET); // <┘ CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Test_Optimize_StaticMath_DIV() { using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH10); scriptBefore.Emit(VM.OpCode.PUSH11); scriptBefore.Emit(VM.OpCode.DIV); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.EmitPush(10 / 11); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.Emit(VM.OpCode.PUSH11); scriptBefore.Emit(VM.OpCode.PUSH10); scriptBefore.Emit(VM.OpCode.DIV); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.EmitPush(11 / 10); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } using (var scriptBefore = new ScriptBuilder()) { scriptBefore.EmitPush(ushort.MaxValue); scriptBefore.EmitPush(short.MaxValue); scriptBefore.Emit(VM.OpCode.DIV); using (var scriptAfter = new ScriptBuilder()) { scriptAfter.EmitPush(BigInteger.Divide(new BigInteger(ushort.MaxValue), new BigInteger(short.MaxValue))); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_CONST_EXECUTION); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } } }
private void Test_Optimize_Recalculate_Positive_JMPX_L(VM.OpCode biGJumpOpCode) { var smallJumpOpCode = (VM.OpCode)(biGJumpOpCode - 1); using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(biGJumpOpCode, ToJumpLArg(7)); // ─┐ scriptBefore.Emit(VM.OpCode.NOP); // │ scriptBefore.Emit(VM.OpCode.NOP); // │ scriptBefore.Emit(VM.OpCode.RET); // <┘ var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray()); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(smallJumpOpCode, ToJumpArg(2)); // ─┐ scriptAfter.Emit(VM.OpCode.RET); // <┘ CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Test_OptimizeSkip_Recalculate_BoolEqualTrue() { //jmp will cause skip this equal optimize using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.JMP, new byte[2]); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.PUSH1); scriptBefore.Emit(VM.OpCode.EQUAL); scriptBefore.Emit(VM.OpCode.NOP); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.PUSH1); scriptAfter.Emit(VM.OpCode.NOP); var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), OptimizeParserType.DELETE_USELESS_EQUAL); CollectionAssert.AreNotEqual(scriptAfter.ToArray(), optimized); CollectionAssert.AreEqual(scriptBefore.ToArray(), optimized); }
public void Test_Optimize_Recalculate_Positive_PUSHA() { using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.PUSHA, ToJumpLArg(7)); // ─┐ scriptBefore.Emit(VM.OpCode.NOP); // │ scriptBefore.Emit(VM.OpCode.NOP); // │ scriptBefore.Emit(VM.OpCode.RET); // <┘ var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), Array.Empty <int>(), OptimizeParserType.DELETE_DEAD_CODE | OptimizeParserType.USE_SHORT_ADDRESS ); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.PUSHA, ToJumpLArg(5)); // ─┐ scriptAfter.Emit(VM.OpCode.RET); // <┘ CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
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(), Array.Empty <int>(), OptimizeParserType.DELETE_USELESS_EQUAL | OptimizeParserType.DELETE_NOP); scriptAfter.Emit(VM.OpCode.PUSH1); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); } }
public void Test_Optimize_JMP_LNext() { using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.JMP_L, ToJumpLArg(5)); // ───┐ scriptBefore.Emit(VM.OpCode.PUSH1); // <──┘ // useshortaddress before deleteuselessjmp var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), new OptimizeParserType[] { OptimizeParserType.USE_SHORT_ADDRESS, OptimizeParserType.DELETE_USERLESS_JMP }); using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.PUSH1); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); // deleteuselessjmp before useshortaddress optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), new OptimizeParserType[] { OptimizeParserType.DELETE_USERLESS_JMP, OptimizeParserType.USE_SHORT_ADDRESS }); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); // use deleteuselessjmp only optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), new OptimizeParserType[] { OptimizeParserType.DELETE_USERLESS_JMP }); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Test_Optimize_Recalculate_Negative_PUSHA() { using var scriptBefore = new ScriptBuilder(); scriptBefore.Emit(VM.OpCode.PUSHA, ToJumpLArg(9)); // ───┐ scriptBefore.Emit(VM.OpCode.PUSH1); // <┐ │ scriptBefore.Emit(VM.OpCode.RET); // │ │ scriptBefore.Emit(VM.OpCode.NOP); // │ │ scriptBefore.Emit(VM.OpCode.NOP); // │ │ scriptBefore.Emit(VM.OpCode.PUSHA, ToJumpLArg(-4)); // x<┘ using var scriptAfter = new ScriptBuilder(); scriptAfter.Emit(VM.OpCode.PUSHA, ToJumpLArg(7)); // ───┐ scriptAfter.Emit(VM.OpCode.PUSH1); // <┐ │ scriptAfter.Emit(VM.OpCode.RET); // │ │ scriptAfter.Emit(VM.OpCode.PUSHA, ToJumpLArg(-2)); // x<┘ var optimized = NefOptimizeTool.Optimize(scriptBefore.ToArray(), OptimizeParserType.DELETE_DEAD_CODE, OptimizeParserType.USE_SHORT_ADDRESS ); CollectionAssert.AreEqual(scriptAfter.ToArray(), optimized); }
public void Build(Stream fs, Stream fspdb, bool optimizer) { this.IsBuild = false; this.Error = null; this.UseOptimizer = optimizer; var log = new DefLogger(); this.modIL = new ILModule(log); try { modIL.LoadModule(fs, fspdb); } catch (Exception err) { log.Log("LoadModule Error:" + err.ToString()); this.Error = err; return; } converterIL = new ModuleConverter(log); Dictionary <int, int> addrConvTable = null; ConvOption option = new ConvOption(); #if NDEBUG try #endif { converterIL.Convert(modIL, option); finalNEFScript = converterIL.outModule.Build(); if (optimizer) { List <int> entryPoints = new List <int>(); foreach (var f in converterIL.outModule.mapMethods.Values) { if (!entryPoints.Contains(f.funcaddr)) { entryPoints.Add(f.funcaddr); } } var opbytes = NefOptimizeTool.Optimize(finalNEFScript, entryPoints.ToArray(), out addrConvTable); float ratio = (opbytes.Length * 100.0f) / (float)finalNEFScript.Length; log.Log("optimization ratio = " + ratio + "%"); finalNEFScript = opbytes; } IsBuild = true; } #if NDEBUG catch (Exception err) { this.Error = err; log.Log("Convert IL->ASM Error:" + err.ToString()); return; } #endif try { finalABI = FuncExport.GenerateAbi(converterIL.outModule, addrConvTable); } catch (Exception err) { log.Log("Gen Abi Error:" + err.ToString()); this.Error = err; return; } try { debugInfo = DebugExport.Export(converterIL.outModule, finalNEFScript, addrConvTable); } catch (Exception err) { log.Log("Gen debugInfo Error:" + err.ToString()); this.Error = err; return; } try { finalManifest = FuncExport.GenerateManifest(finalABI, converterIL.outModule); } catch (Exception err) { log.Log("Gen Manifest Error:" + err.ToString()); this.Error = err; return; } try { nefFile = new NefFile { Compiler = "neon-" + Version.Parse(((AssemblyFileVersionAttribute)Assembly.GetAssembly(typeof(Program)) .GetCustomAttribute(typeof(AssemblyFileVersionAttribute))).Version).ToString(), Tokens = converterIL.methodTokens.ToArray(), Script = finalNEFScript }; nefFile.CheckSum = NefFile.ComputeChecksum(nefFile); } catch (Exception err) { log.Log("Write Bytes Error:" + err.ToString()); return; } }
public void Build(Stream fs, Stream fspdb, bool optimizer) { this.IsBuild = false; this.Error = null; this.UseOptimizer = optimizer; var log = new DefLogger(); this.modIL = new ILModule(log); try { modIL.LoadModule(fs, fspdb); } catch (Exception err) { log.Log("LoadModule Error:" + err.ToString()); this.Error = err; return; } converterIL = new ModuleConverter(log); Dictionary <int, int> addrConvTable = null; ConvOption option = new ConvOption(); #if NDEBUG try #endif { converterIL.Convert(modIL, option); finalNEFScript = converterIL.outModule.Build(); if (optimizer) { List <int> entryPoints = new List <int>(); foreach (var f in converterIL.outModule.mapMethods.Values) { if (!entryPoints.Contains(f.funcaddr)) { entryPoints.Add(f.funcaddr); } } var opbytes = NefOptimizeTool.Optimize(finalNEFScript, entryPoints.ToArray(), out addrConvTable); float ratio = (opbytes.Length * 100.0f) / (float)finalNEFScript.Length; log.Log("optimization ratio = " + ratio + "%"); finalNEFScript = opbytes; } IsBuild = true; } #if NDEBUG catch (Exception err) { this.Error = err; log.Log("Convert IL->ASM Error:" + err.ToString()); return; } #endif try { finalABI = FuncExport.GenerateAbi(converterIL.outModule, addrConvTable); } catch (Exception err) { log.Log("Gen Abi Error:" + err.ToString()); this.Error = err; return; } try { debugInfo = DebugExport.Export(converterIL.outModule, finalNEFScript, addrConvTable); } catch (Exception err) { log.Log("Gen debugInfo Error:" + err.ToString()); this.Error = err; return; } try { finalManifest = FuncExport.GenerateManifest(finalABI, converterIL.outModule); } catch (Exception err) { log.Log("Gen Manifest Error:" + err.ToString()); this.Error = err; return; } }
public static int Compile(Options options) { // Set console Console.OutputEncoding = Encoding.UTF8; var log = new DefLogger(); log.Log("Neo.Compiler.MSIL console app v" + Assembly.GetEntryAssembly().GetName().Version); var fileInfo = new FileInfo(options.File); // Set current directory if (!fileInfo.Exists) { log.Log("Could not find file " + fileInfo.FullName); return(-1); } Stream fs; Stream fspdb; var onlyname = Path.GetFileNameWithoutExtension(fileInfo.Name); var path = fileInfo.Directory.FullName; if (!string.IsNullOrEmpty(path)) { try { Directory.SetCurrentDirectory(path); } catch { log.Log("Could not find path: " + path); return(-1); } } switch (fileInfo.Extension.ToLowerInvariant()) { case ".csproj": { // Compile csproj file log.Log("Compiling from csproj project"); var output = Compiler.CompileCSProj(fileInfo.FullName); fs = new MemoryStream(output.Dll); fspdb = new MemoryStream(output.Pdb); break; } case ".vbproj": { // Compile vbproj file log.Log("Compiling from vbproj project"); var output = Compiler.CompileVBProj(fileInfo.FullName); fs = new MemoryStream(output.Dll); fspdb = new MemoryStream(output.Pdb); break; } case ".cs": { // Compile C# files log.Log("Compiling from c# source"); var output = Compiler.CompileCSFiles(new string[] { fileInfo.FullName }, new string[0]); fs = new MemoryStream(output.Dll); fspdb = new MemoryStream(output.Pdb); break; } case ".vb": { // Compile VB files log.Log("Compiling from VB source"); var output = Compiler.CompileVBFiles(new string[] { fileInfo.FullName }, new string[0]); fs = new MemoryStream(output.Dll); fspdb = new MemoryStream(output.Pdb); break; } case ".dll": { string filepdb = onlyname + ".pdb"; // Open file try { fs = fileInfo.OpenRead(); if (File.Exists(filepdb)) { fspdb = File.OpenRead(filepdb); } else { fspdb = null; } } catch (Exception err) { log.Log("Open File Error:" + err.ToString()); return(-1); } break; } default: { log.Log("File format not supported by neon: " + path); return(-1); } } ILModule mod = new ILModule(log); // Load module try { mod.LoadModule(fs, fspdb); } catch (Exception err) { log.Log("LoadModule Error:" + err.ToString()); return(-1); } byte[] bytes; int bSucc = 0; string jsonstr = null; NeoModule module = null; // Convert and build try { var conv = new ModuleConverter(log); ConvOption option = new ConvOption(); module = conv.Convert(mod, option); bytes = module.Build(); log.Log("convert succ"); if (options.Optimize) { var optimize = NefOptimizeTool.Optimize(bytes); log.Log("optimization succ " + (((bytes.Length / (optimize.Length + 0.0)) * 100.0) - 100).ToString("0.00 '%'")); bytes = optimize; } try { var outjson = vmtool.FuncExport.Export(module, bytes); StringBuilder sb = new StringBuilder(); outjson.ConvertToStringWithFormat(sb, 0); jsonstr = sb.ToString(); log.Log("gen abi succ"); } catch (Exception err) { log.Log("gen abi Error:" + err.ToString()); } } catch (Exception err) { log.Log("Convert Error:" + err.ToString()); return(-1); } // Write bytes try { string bytesname = onlyname + ".nef"; var nef = new NefFile { Compiler = "neon", Version = Version.Parse(((AssemblyFileVersionAttribute)Assembly.GetExecutingAssembly() .GetCustomAttribute(typeof(AssemblyFileVersionAttribute))).Version), Script = bytes, ScriptHash = bytes.ToScriptHash() }; nef.CheckSum = NefFile.ComputeChecksum(nef); File.Delete(bytesname); using (var stream = File.OpenWrite(bytesname)) using (var writer = new BinaryWriter(stream)) { nef.Serialize(writer); } log.Log("write:" + bytesname); bSucc++; } catch (Exception err) { log.Log("Write Bytes Error:" + err.ToString()); return(-1); } try { string abiname = onlyname + ".abi.json"; File.Delete(abiname); File.WriteAllText(abiname, jsonstr); log.Log("write:" + abiname); bSucc++; } catch (Exception err) { log.Log("Write abi Error:" + err.ToString()); return(-1); } try { var features = module == null ? ContractFeatures.NoProperty : module.attributes .Where(u => u.AttributeType.Name == "FeaturesAttribute") .Select(u => (ContractFeatures)u.ConstructorArguments.FirstOrDefault().Value) .FirstOrDefault(); var extraAttributes = module == null ? new List <Mono.Collections.Generic.Collection <CustomAttributeArgument> >() : module.attributes.Where(u => u.AttributeType.Name == "ManifestExtraAttribute").Select(attribute => attribute.ConstructorArguments).ToList(); var extra = BuildExtraAttributes(extraAttributes); var storage = features.HasFlag(ContractFeatures.HasStorage).ToString().ToLowerInvariant(); var payable = features.HasFlag(ContractFeatures.Payable).ToString().ToLowerInvariant(); string manifest = onlyname + ".manifest.json"; string defManifest = @"{""groups"":[],""features"":{""storage"":" + storage + @",""payable"":" + payable + @"},""abi"":" + jsonstr + @",""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":" + extra + "}"; File.Delete(manifest); File.WriteAllText(manifest, defManifest); log.Log("write:" + manifest); bSucc++; } catch (Exception err) { log.Log("Write manifest Error:" + err.ToString()); return(-1); } try { fs.Dispose(); if (fspdb != null) { fspdb.Dispose(); } } catch { } if (bSucc == 3) { log.Log("SUCC"); return(0); } return(-1); }
public void Build(Stream fs, Stream fspdb, bool optimizer) { this.IsBuild = false; this.Error = null; this.UseOptimizer = optimizer; var log = new DefLogger(); this.modIL = new ILModule(log); try { modIL.LoadModule(fs, fspdb); } catch (Exception err) { log.Log("LoadModule Error:" + err.ToString()); this.Error = err; return; } converterIL = new ModuleConverter(log); Dictionary <int, int> addrConvTable = null; ConvOption option = new ConvOption(); #if NDEBUG try #endif { converterIL.Convert(modIL, option); finalNEF = converterIL.outModule.Build(); if (optimizer) { var opbytes = NefOptimizeTool.Optimize(finalNEF, out addrConvTable); float ratio = (opbytes.Length * 100.0f) / (float)finalNEF.Length; log.Log("optimization ratio = " + ratio + "%"); finalNEF = opbytes; } IsBuild = true; } #if NDEBUG catch (Exception err) { this.Error = err; log.Log("Convert IL->ASM Error:" + err.ToString()); return; } #endif try { finialABI = vmtool.FuncExport.Export(converterIL.outModule, finalNEF, addrConvTable); } catch (Exception e) { throw e; } try { var features = converterIL.outModule == null ? ContractFeatures.NoProperty : converterIL.outModule.attributes .Where(u => u.AttributeType.Name == "FeaturesAttribute") .Select(u => (ContractFeatures)u.ConstructorArguments.FirstOrDefault().Value) .FirstOrDefault(); var extraAttributes = converterIL.outModule == null ? new List <Mono.Collections.Generic.Collection <CustomAttributeArgument> >() : converterIL.outModule.attributes.Where(u => u.AttributeType.Name == "ManifestExtraAttribute").Select(attribute => attribute.ConstructorArguments).ToList(); var storage = features.HasFlag(ContractFeatures.HasStorage).ToString().ToLowerInvariant(); var payable = features.HasFlag(ContractFeatures.Payable).ToString().ToLowerInvariant(); finalManifest = @"{""groups"":[],""features"":{""storage"":" + storage + @",""payable"":" + payable + @"},""abi"":" + finialABI + @",""permissions"":[{""contract"":""*"",""methods"":""*""}],""trusts"":[],""safeMethods"":[],""extra"":[]" + "}"; } catch { } }
public static int Compile(Options options, ILogger log = null) { // Set console Console.OutputEncoding = Encoding.UTF8; log ??= new DefLogger(); log.Log("Neo.Compiler.MSIL console app v" + Assembly.GetAssembly(typeof(Program)).GetName().Version); var fileInfo = new FileInfo(options.File); // Set current directory if (!fileInfo.Exists) { log.Log("Could not find file " + fileInfo.FullName); return(-1); } Stream fs; Stream fspdb; var onlyname = Path.GetFileNameWithoutExtension(fileInfo.Name); var path = fileInfo.Directory.FullName; if (!string.IsNullOrEmpty(path)) { try { Directory.SetCurrentDirectory(path); } catch { log.Log("Could not find path: " + path); return(-1); } } switch (fileInfo.Extension.ToLowerInvariant()) { case ".csproj": { // Compile csproj file log.Log("Compiling from csproj project"); var output = Compiler.CompileCSProj(fileInfo.FullName); fs = new MemoryStream(output.Dll); fspdb = new MemoryStream(output.Pdb); break; } case ".vbproj": { // Compile vbproj file log.Log("Compiling from vbproj project"); var output = Compiler.CompileVBProj(fileInfo.FullName); fs = new MemoryStream(output.Dll); fspdb = new MemoryStream(output.Pdb); break; } case ".cs": { // Compile C# files log.Log("Compiling from c# source"); var output = Compiler.CompileCSFiles(new string[] { fileInfo.FullName }, new string[0]); fs = new MemoryStream(output.Dll); fspdb = new MemoryStream(output.Pdb); break; } case ".vb": { // Compile VB files log.Log("Compiling from VB source"); var output = Compiler.CompileVBFiles(new string[] { fileInfo.FullName }, new string[0]); fs = new MemoryStream(output.Dll); fspdb = new MemoryStream(output.Pdb); break; } case ".dll": { string filepdb = onlyname + ".pdb"; // Open file try { fs = fileInfo.OpenRead(); if (File.Exists(filepdb)) { fspdb = File.OpenRead(filepdb); } else { fspdb = null; } } catch (Exception err) { log.Log("Open File Error:" + err.ToString()); return(-1); } break; } default: { log.Log("File format not supported by neon: " + path); return(-1); } } ILModule mod = new ILModule(log); // Load module try { mod.LoadModule(fs, fspdb); } catch (Exception err) { log.Log("LoadModule Error:" + err.ToString()); return(-1); } JObject abi; byte[] bytes; int bSucc = 0; string debugstr = null; NeoModule module; // Convert and build try { var conv = new ModuleConverter(log); ConvOption option = new ConvOption(); module = conv.Convert(mod, option); bytes = module.Build(); log.Log("convert succ"); Dictionary <int, int> addrConvTable = null; if (options.Optimize) { HashSet <int> entryPoints = new HashSet <int>(); foreach (var func in module.mapMethods) { entryPoints.Add(func.Value.funcaddr); } var optimize = NefOptimizeTool.Optimize(bytes, entryPoints.ToArray(), out addrConvTable); log.Log("optimization succ " + (((bytes.Length / (optimize.Length + 0.0)) * 100.0) - 100).ToString("0.00 '%'")); bytes = optimize; } try { abi = FuncExport.Export(module, bytes, addrConvTable); log.Log("gen abi succ"); } catch (Exception err) { log.Log("gen abi Error:" + err.ToString()); return(-1); } try { var outjson = DebugExport.Export(module, bytes, addrConvTable); debugstr = outjson.ToString(false); log.Log("gen debug succ"); } catch (Exception err) { log.Log("gen debug Error:" + err.ToString()); } } catch (Exception err) { log.Log("Convert Error:" + err.ToString()); return(-1); } // Write bytes try { string bytesname = onlyname + ".nef"; var nef = new NefFile { Compiler = "neon", Version = Version.Parse(((AssemblyFileVersionAttribute)Assembly.GetAssembly(typeof(Program)) .GetCustomAttribute(typeof(AssemblyFileVersionAttribute))).Version), Script = bytes, ScriptHash = bytes.ToScriptHash() }; nef.CheckSum = NefFile.ComputeChecksum(nef); File.Delete(bytesname); using (var stream = File.OpenWrite(bytesname)) using (var writer = new BinaryWriter(stream)) { nef.Serialize(writer); } log.Log("write:" + bytesname); bSucc++; } catch (Exception err) { log.Log("Write Bytes Error:" + err.ToString()); return(-1); } try { var sbABI = abi.ToString(false); string abiname = onlyname + ".abi.json"; File.Delete(abiname); File.WriteAllText(abiname, sbABI.ToString()); log.Log("write:" + abiname); bSucc++; } catch (Exception err) { log.Log("Write abi Error:" + err.ToString()); return(-1); } try { string debugname = onlyname + ".debug.json"; string debugzip = onlyname + ".nefdbgnfo"; var tempName = Path.GetTempFileName(); File.Delete(tempName); File.WriteAllText(tempName, debugstr); File.Delete(debugzip); using (var archive = ZipFile.Open(debugzip, ZipArchiveMode.Create)) { archive.CreateEntryFromFile(tempName, Path.GetFileName(debugname)); } File.Delete(tempName); log.Log("write:" + debugzip); bSucc++; } catch (Exception err) { log.Log("Write debug Error:" + err.ToString()); return(-1); } try { string manifest = onlyname + ".manifest.json"; var defManifest = FuncExport.GenerateManifest(abi, module); File.Delete(manifest); File.WriteAllText(manifest, defManifest); log.Log("write:" + manifest); bSucc++; } catch (Exception err) { log.Log("Write manifest Error:" + err.ToString()); return(-1); } try { fs.Dispose(); if (fspdb != null) { fspdb.Dispose(); } } catch { } if (bSucc == 4) { log.Log("SUCC"); return(0); } return(-1); }