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); }
private NeoCode _Convert1by1(VM.OpCode code, OpCode src, NeoMethod to, byte[] data = null) { NeoCode _code = new NeoCode(); int startaddr = addr; _code.addr = addr; if (src != null) { addrconv[src.addr] = addr; _code.debugcode = src.debugcode; _code.debugline = src.debugline; _code.debugILAddr = src.addr; _code.debugILCode = src.code.ToString(); } addr++; _code.code = code; if (data != null) { _code.bytes = data; addr += _code.bytes.Length; } to.body_Codes[startaddr] = _code; return(_code); }
public void SetParam(VM.OpCode _op, byte[] data) { var op = curScript.ops.Last(); if (op.op == _op) { op.opparam = data; } }
void LogResult(VM.OpCode nextOpcode, VM.ExecutionStackRecord.Op[] records, VM.StackItem lastrecord) { if (records != null && records.Length > 0) { this.FullLog.OPStackRecord(records.ToArray()); } if (lastrecord != null) { this.FullLog.OpResult(lastrecord); } }
public bool CalcCalcStack(VM.OpCode op) { if (op == VM.OpCode.TOALTSTACK) { var p = CalcStack.Pop(); AltStack.Push(p); StateID++; return(true); } if (op == VM.OpCode.FROMALTSTACK) { var p = AltStack.Pop(); CalcStack.Push(p); StateID++; return(true); } if (op == VM.OpCode.XSWAP) { var item = CalcStack.Pop(); var xn = CalcStack.Peek(item.AsInt()); var swapv = CalcStack.Peek(0); CalcStack.Set(item.AsInt(), swapv); CalcStack.Set(0, xn); StateID++; return(true); } if (op == VM.OpCode.SWAP) { var v1 = CalcStack.Pop(); var v2 = CalcStack.Pop(); CalcStack.Push(v1); CalcStack.Push(v2); StateID++; return(true); } if (op == VM.OpCode.ROT) { var v3 = CalcStack.Pop(); var v2 = CalcStack.Pop(); var v1 = CalcStack.Pop(); CalcStack.Push(v2); CalcStack.Push(v3); CalcStack.Push(v1); StateID++; return(true); } //if (op == VM.OpCode.ROLL) //{ // int n = (int)CalcStack.Pop().AsInt(); // CalcStack.Push(CalcStack.Remove(n)); // return true; //} return(false); }
private int _ConvertNewObj(OpCode src, NeoMethod to) { var _type = (src.tokenUnknown as Mono.Cecil.MethodReference); if (_type.FullName == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])") { return(0);//donothing; } else if (_type.DeclaringType.FullName.Contains("Exception")) { _Convert1by1(VM.OpCode.NOP, src, to);//空白 var pcount = _type.Parameters.Count; for (var i = 0; i < pcount; i++) { _Insert1(VM.OpCode.DROP, "", to); } return(0); } var type = _type.Resolve(); //如果构造函数上有一个[OpCode],替换New Array操作 foreach (var m in type.DeclaringType.Methods) { if (m.IsConstructor && m.HasCustomAttributes) { foreach (var attr in m.CustomAttributes) { if (attr.AttributeType.Name == "OpCodeAttribute") { //var _type = attr.ConstructorArguments[0].Type; var value = (byte)attr.ConstructorArguments[0].Value; VM.OpCode v = (VM.OpCode)value; _Insert1(v, null, to); return(0); } } } } _Convert1by1(VM.OpCode.NOP, src, to); //空白 _ConvertPush(type.DeclaringType.Fields.Count, null, to); //插入个数量 if (type.DeclaringType.IsValueType) { _Insert1(VM.OpCode.NEWSTRUCT, null, to); } else { _Insert1(VM.OpCode.NEWARRAY, null, to); } return(0); }
public void NextOp(int addr, VM.OpCode op) { LogOp _op = new LogOp(addr, op); curScript.ops.Add(_op); curOp = _op; if (op == VM.OpCode.RET || op == VM.OpCode.TAILCALL) { if (curScript.parent != null) { curScript = curScript.parent; } } }
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); }
private NeoCode _Insert1(VM.OpCode code, string comment, NeoMethod to, byte[] data = null) { NeoCode _code = new NeoCode(); int startaddr = addr; _code.addr = addr; { _code.debugcode = comment; _code.debugline = 0; } addr++; _code.code = code; if (data != null) { _code.bytes = data; addr += _code.bytes.Length; } to.body_Codes[startaddr] = _code; return(_code); }
public bool CalcCalcStack(VM.OpCode op) { if (op == VM.OpCode.TOALTSTACK) { var p = CalcStack.Pop(); AltStack.Push(p); StateID++; return(true); } if (op == VM.OpCode.FROMALTSTACK) { var p = AltStack.Pop(); CalcStack.Push(p); StateID++; return(true); } if (op == VM.OpCode.XSWAP) { var item = CalcStack.Pop(); var xn = CalcStack.Peek(item.AsInt()); var swapv = CalcStack.Peek(0); CalcStack.Set(item.AsInt(), swapv); CalcStack.Set(0, xn); StateID++; return(true); } if (op == VM.OpCode.SWAP) { var v1 = CalcStack.Pop(); var v2 = CalcStack.Pop(); CalcStack.Push(v1); CalcStack.Push(v2); StateID++; return(true); } return(false); }
private int ConvertCode(ILMethod method, OpCode src, NeoMethod to) { int skipcount = 0; switch (src.code) { case CodeEx.Nop: _Convert1by1(VM.OpCode.NOP, src, to); break; case CodeEx.Ret: //return 在外面特殊处理了 _Insert1(VM.OpCode.RET, null, to); break; case CodeEx.Pop: _Convert1by1(VM.OpCode.DROP, src, to); break; case CodeEx.Ldnull: _ConvertPush(new byte[0], src, to); break; case CodeEx.Ldc_I4: case CodeEx.Ldc_I4_S: skipcount = _ConvertPushI4WithConv(method, src.tokenI32, src, to); break; case CodeEx.Ldc_I4_0: _ConvertPush(0, src, to); break; case CodeEx.Ldc_I4_1: _ConvertPush(1, src, to); break; case CodeEx.Ldc_I4_2: _ConvertPush(2, src, to); break; case CodeEx.Ldc_I4_3: _ConvertPush(3, src, to); break; case CodeEx.Ldc_I4_4: _ConvertPush(4, src, to); break; case CodeEx.Ldc_I4_5: _ConvertPush(5, src, to); break; case CodeEx.Ldc_I4_6: _ConvertPush(6, src, to); break; case CodeEx.Ldc_I4_7: _ConvertPush(7, src, to); break; case CodeEx.Ldc_I4_8: _ConvertPush(8, src, to); break; case CodeEx.Ldc_I4_M1: skipcount = _ConvertPushI4WithConv(method, -1, src, to); break; case CodeEx.Ldc_I8: skipcount = _ConvertPushI8WithConv(method, src.tokenI64, src, to); break; case CodeEx.Ldstr: _ConvertPush(Encoding.UTF8.GetBytes(src.tokenStr), src, to); break; case CodeEx.Stloc_0: _ConvertStLoc(method, src, to, 0); break; case CodeEx.Stloc_1: _ConvertStLoc(method, src, to, 1); break; case CodeEx.Stloc_2: _ConvertStLoc(method, src, to, 2); break; case CodeEx.Stloc_3: _ConvertStLoc(method, src, to, 3); break; case CodeEx.Stloc_S: _ConvertStLoc(method, src, to, src.tokenI32); break; case CodeEx.Ldloc_0: _ConvertLdLoc(method, src, to, 0); break; case CodeEx.Ldloc_1: _ConvertLdLoc(method, src, to, 1); break; case CodeEx.Ldloc_2: _ConvertLdLoc(method, src, to, 2); break; case CodeEx.Ldloc_3: _ConvertLdLoc(method, src, to, 3); break; case CodeEx.Ldloc_S: _ConvertLdLoc(method, src, to, src.tokenI32); break; case CodeEx.Ldarg_0: _ConvertLdArg(method, src, to, 0); break; case CodeEx.Ldarg_1: _ConvertLdArg(method, src, to, 1); break; case CodeEx.Ldarg_2: _ConvertLdArg(method, src, to, 2); break; case CodeEx.Ldarg_3: _ConvertLdArg(method, src, to, 3); break; case CodeEx.Ldarg_S: case CodeEx.Ldarg: case CodeEx.Ldarga: case CodeEx.Ldarga_S: _ConvertLdArg(method, src, to, src.tokenI32); break; case CodeEx.Starg_S: case CodeEx.Starg: _ConvertStArg(src, to, src.tokenI32); break; //需要地址轉換的情況 case CodeEx.Br: case CodeEx.Br_S: case CodeEx.Leave: case CodeEx.Leave_S: { var code = _Convert1by1(VM.OpCode.JMP, src, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Switch: { throw new Exception("need neo.VM update."); //var addrdata = new byte[src.tokenAddr_Switch.Length * 2 + 2]; //var shortaddrcount = (UInt16)src.tokenAddr_Switch.Length; //var data = BitConverter.GetBytes(shortaddrcount); //addrdata[0] = data[0]; //addrdata[1] = data[1]; //var code = _Convert1by1(VM.OpCode.SWITCH, src, to, addrdata); //code.needfix = true; //code.srcaddrswitch = new int[shortaddrcount]; //for (var i = 0; i < shortaddrcount; i++) //{ // code.srcaddrswitch[i] = src.tokenAddr_Switch[i]; //} } break; case CodeEx.Brtrue: case CodeEx.Brtrue_S: { var code = _Convert1by1(VM.OpCode.JMPIF, src, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Brfalse: case CodeEx.Brfalse_S: { var code = _Convert1by1(VM.OpCode.JMPIFNOT, src, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Beq: case CodeEx.Beq_S: { _Convert1by1(VM.OpCode.NUMEQUAL, src, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Bne_Un: case CodeEx.Bne_Un_S: { _Convert1by1(VM.OpCode.ABS, src, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.ABS, null, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.NUMNOTEQUAL, null, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Blt: case CodeEx.Blt_S: { _Convert1by1(VM.OpCode.LT, src, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Blt_Un: case CodeEx.Blt_Un_S: { _Convert1by1(VM.OpCode.ABS, src, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.ABS, null, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.LT, null, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Ble: case CodeEx.Ble_S: { _Convert1by1(VM.OpCode.LTE, src, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Ble_Un: case CodeEx.Ble_Un_S: { _Convert1by1(VM.OpCode.ABS, src, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.ABS, null, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.LTE, null, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Bgt: case CodeEx.Bgt_S: { _Convert1by1(VM.OpCode.GT, src, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Bgt_Un: case CodeEx.Bgt_Un_S: { _Convert1by1(VM.OpCode.ABS, src, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.ABS, null, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.GT, null, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Bge: case CodeEx.Bge_S: { _Convert1by1(VM.OpCode.GTE, src, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; case CodeEx.Bge_Un: case CodeEx.Bge_Un_S: { _Convert1by1(VM.OpCode.ABS, src, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.ABS, null, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.GTE, null, to); var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; //Stack case CodeEx.Dup: _Convert1by1(VM.OpCode.DUP, src, to); break; //Bitwise logic case CodeEx.And: _Convert1by1(VM.OpCode.AND, src, to); break; case CodeEx.Or: _Convert1by1(VM.OpCode.OR, src, to); break; case CodeEx.Xor: _Convert1by1(VM.OpCode.XOR, src, to); break; case CodeEx.Not: _Convert1by1(VM.OpCode.INVERT, src, to); break; //math case CodeEx.Add: case CodeEx.Add_Ovf: case CodeEx.Add_Ovf_Un: _Convert1by1(VM.OpCode.ADD, src, to); break; case CodeEx.Sub: case CodeEx.Sub_Ovf: case CodeEx.Sub_Ovf_Un: _Convert1by1(VM.OpCode.SUB, src, to); break; case CodeEx.Mul: case CodeEx.Mul_Ovf: case CodeEx.Mul_Ovf_Un: _Convert1by1(VM.OpCode.MUL, src, to); break; case CodeEx.Div: case CodeEx.Div_Un: _Convert1by1(VM.OpCode.DIV, src, to); break; case CodeEx.Rem: case CodeEx.Rem_Un: _Convert1by1(VM.OpCode.MOD, src, to); break; case CodeEx.Neg: _Convert1by1(VM.OpCode.NEGATE, src, to); break; case CodeEx.Shl: _Convert1by1(VM.OpCode.SHL, src, to); break; case CodeEx.Shr: case CodeEx.Shr_Un: _Convert1by1(VM.OpCode.SHR, src, to); break; //logic case CodeEx.Clt: case CodeEx.Clt_Un: _Convert1by1(VM.OpCode.LT, src, to); break; case CodeEx.Cgt: case CodeEx.Cgt_Un: _Convert1by1(VM.OpCode.GT, src, to); break; case CodeEx.Ceq: _Convert1by1(VM.OpCode.NUMEQUAL, src, to); break; //call case CodeEx.Call: case CodeEx.Callvirt: _ConvertCall(src, to); break; //用上一个参数作为数量,new 一个数组 case CodeEx.Newarr: skipcount = _ConvertNewArr(method, src, to); break; //array //用意为byte[] 取一部分..... // en: intent to use byte[] as array..... case CodeEx.Ldelem_U1: case CodeEx.Ldelem_I1: //_ConvertPush(1, src, to); //_Convert1by1(VM.OpCode.SUBSTR, null, to); //break; //now we can use pickitem for byte[] case CodeEx.Ldelem_Any: case CodeEx.Ldelem_I: //case CodeEx.Ldelem_I1: case CodeEx.Ldelem_I2: case CodeEx.Ldelem_I4: case CodeEx.Ldelem_I8: case CodeEx.Ldelem_R4: case CodeEx.Ldelem_R8: case CodeEx.Ldelem_Ref: case CodeEx.Ldelem_U2: case CodeEx.Ldelem_U4: _Convert1by1(VM.OpCode.PICKITEM, src, to); break; case CodeEx.Ldlen: _Convert1by1(VM.OpCode.ARRAYSIZE, src, to); break; case CodeEx.Stelem_I1: { // WILL TRACE VARIABLE ORIGIN "Z" IN ALTSTACK! // EXPECTS: source[index] = b; // index and b must be variables! constants will fail! /* * 9 6a DUPFROMALTSTACK * 8 5Z PUSHZ * 7 c3 PICKITEM * 6 6a DUPFROMALTSTACK * 5 5Y PUSHY * 4 c3 PICKITEM * 3 6a DUPFROMALTSTACK * 2 5X PUSHX * 1 c3 PICKITEM */ if ((to.body_Codes[addr - 1].code == VM.OpCode.PICKITEM) && (to.body_Codes[addr - 4].code == VM.OpCode.PICKITEM) && (to.body_Codes[addr - 7].code == VM.OpCode.PICKITEM) && (to.body_Codes[addr - 3].code == VM.OpCode.DUPFROMALTSTACK) && (to.body_Codes[addr - 6].code == VM.OpCode.DUPFROMALTSTACK) && (to.body_Codes[addr - 9].code == VM.OpCode.DUPFROMALTSTACK) && ((to.body_Codes[addr - 2].code >= VM.OpCode.PUSH0) && (to.body_Codes[addr - 2].code <= VM.OpCode.PUSH16)) && ((to.body_Codes[addr - 5].code >= VM.OpCode.PUSH0) && (to.body_Codes[addr - 5].code <= VM.OpCode.PUSH16)) && ((to.body_Codes[addr - 8].code >= VM.OpCode.PUSH0) && (to.body_Codes[addr - 8].code <= VM.OpCode.PUSH16)) ) { // WILL REQUIRE TO PROCESS INFORMATION AND STORE IT AGAIN ON ALTSTACK CORRECT POSITION VM.OpCode PushZ = to.body_Codes[addr - 8].code; _Convert1by1(VM.OpCode.PUSH2, null, to); _Convert1by1(VM.OpCode.PICK, null, to); _Convert1by1(VM.OpCode.PUSH2, null, to); _Convert1by1(VM.OpCode.PICK, null, to); _Convert1by1(VM.OpCode.LEFT, null, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.CAT, null, to); _Convert1by1(VM.OpCode.ROT, null, to); _Convert1by1(VM.OpCode.ROT, null, to); _Convert1by1(VM.OpCode.OVER, null, to); _Convert1by1(VM.OpCode.ARRAYSIZE, null, to); _Convert1by1(VM.OpCode.DEC, null, to); _Convert1by1(VM.OpCode.SWAP, null, to); _Convert1by1(VM.OpCode.SUB, null, to); _Convert1by1(VM.OpCode.RIGHT, null, to); _Convert1by1(VM.OpCode.CAT, null, to); // FINAL RESULT MUST GO BACK TO POSITION Z ON ALTSTACK // FINAL STACK: // 4 get array (dupfromaltstack) // 3 PushZ // 2 result // 1 setitem _Convert1by1(VM.OpCode.DUPFROMALTSTACK, null, to); // stack: [ array , result , ... ] _Convert1by1(PushZ, null, to); // stack: [ pushz, array , result , ... ] _Convert1by1(VM.OpCode.ROT, null, to); // stack: [ result, pushz, array , ... ] _Convert1by1(VM.OpCode.SETITEM, null, to); // stack: [ result, pushz, array , ... ] } else { throw new Exception("neomachine currently supports only variable indexed bytearray attribution, example: byte[] source; int index = 0; byte b = 1; source[index] = b;"); } } // end case break; case CodeEx.Stelem_Any: case CodeEx.Stelem_I: //case CodeEx.Stelem_I1: case CodeEx.Stelem_I2: case CodeEx.Stelem_I4: case CodeEx.Stelem_I8: case CodeEx.Stelem_R4: case CodeEx.Stelem_R8: case CodeEx.Stelem_Ref: _Convert1by1(VM.OpCode.SETITEM, src, to); break; case CodeEx.Isinst: //支持处理as 表达式 break; case CodeEx.Castclass: _ConvertCastclass(method, src, to); break; case CodeEx.Box: case CodeEx.Unbox: case CodeEx.Unbox_Any: case CodeEx.Break: //也有可能以后利用这个断点调试 case CodeEx.Conv_I: case CodeEx.Conv_I1: case CodeEx.Conv_I2: case CodeEx.Conv_I4: case CodeEx.Conv_I8: case CodeEx.Conv_Ovf_I: case CodeEx.Conv_Ovf_I_Un: case CodeEx.Conv_Ovf_I1: case CodeEx.Conv_Ovf_I1_Un: case CodeEx.Conv_Ovf_I2: case CodeEx.Conv_Ovf_I2_Un: case CodeEx.Conv_Ovf_I4: case CodeEx.Conv_Ovf_I4_Un: case CodeEx.Conv_Ovf_I8: case CodeEx.Conv_Ovf_I8_Un: case CodeEx.Conv_Ovf_U: case CodeEx.Conv_Ovf_U_Un: case CodeEx.Conv_Ovf_U1: case CodeEx.Conv_Ovf_U1_Un: case CodeEx.Conv_Ovf_U2: case CodeEx.Conv_Ovf_U2_Un: case CodeEx.Conv_Ovf_U4: case CodeEx.Conv_Ovf_U4_Un: case CodeEx.Conv_Ovf_U8: case CodeEx.Conv_Ovf_U8_Un: case CodeEx.Conv_U: case CodeEx.Conv_U1: case CodeEx.Conv_U2: case CodeEx.Conv_U4: case CodeEx.Conv_U8: break; /////////////////////////////////////////////// //以下因为支持结构体而出现 //加载一个引用,这里改为加载一个pos值 case CodeEx.Ldloca: case CodeEx.Ldloca_S: _ConvertLdLocA(method, src, to, src.tokenI32); break; case CodeEx.Initobj: _ConvertInitObj(src, to); break; case CodeEx.Newobj: _ConvertNewObj(src, to); break; case CodeEx.Stfld: _ConvertStfld(method, src, to); break; case CodeEx.Ldfld: _ConvertLdfld(src, to); break; case CodeEx.Ldsfld: { _Convert1by1(VM.OpCode.NOP, src, to); var d = src.tokenUnknown as Mono.Cecil.FieldDefinition; //如果是readonly,可以pull个常量上来的 if ( ((d.Attributes & Mono.Cecil.FieldAttributes.InitOnly) > 0) && ((d.Attributes & Mono.Cecil.FieldAttributes.Static) > 0) ) { var fname = d.DeclaringType.FullName + "::" + d.Name; var _src = outModule.staticfields[fname]; if (_src is byte[]) { var bytesrc = (byte[])_src; _ConvertPush(bytesrc, src, to); } else if (_src is int) { var intsrc = (int)_src; _ConvertPush(intsrc, src, to); } else if (_src is long) { var intsrc = (long)_src; _ConvertPush(intsrc, src, to); } else if (_src is Boolean) { var bsrc = (Boolean)_src; _ConvertPush(bsrc ? 1 : 0, src, to); } else if (_src is string) { var bytesrc = System.Text.Encoding.UTF8.GetBytes((string)_src); _ConvertPush(bytesrc, src, to); } else if (_src is BigInteger) { byte[] bytes = ((BigInteger)_src).ToByteArray(); _ConvertPush(bytes, src, to); } else { throw new Exception("not support type Ldsfld\r\n in: " + to.name + "\r\n"); } break; } //如果是调用event导致的这个代码,只找出他的名字 if (d.DeclaringType.HasEvents) { foreach (var ev in d.DeclaringType.Events) { if (ev.Name == d.Name && ev.EventType.FullName == d.FieldType.FullName) { Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = ev.CustomAttributes; to.lastsfieldname = d.Name; foreach (var attr in ca) { if (attr.AttributeType.Name == "DisplayNameAttribute") { to.lastsfieldname = (string)attr.ConstructorArguments[0].Value; } } break; } } } else { //如果走到这里,是一个静态成员,但是没有添加readonly 表示 throw new Exception("Just allow defined a static variable with readonly." + d.FullName); } } break; case CodeEx.Throw: { _Convert1by1(VM.OpCode.THROW, src, to); //throw 会让vm 挂起 //不需要再插入return //_Insert1(VM.OpCode.RET, "", to); } break; default: #if WITHPDB logger.Log("unsupported instruction " + src.code + "\r\n in: " + to.name + "\r\n"); break; #else throw new Exception("unsupported instruction " + src.code + "\r\n in: " + to.name + "\r\n"); #endif } return(skipcount); }
public LogOp(int addr, VM.OpCode op) { this.addr = addr; this.op = op; }
private int _ConvertCall(OpCode src, AntsMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; VM.OpCode callcode = VM.OpCode.NOP; if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else if (refs.ReturnType.Name == "ExecutionEngine") { //donothing 語法過渡類型 return(0); } else {//maybe a syscall // or other if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") { _Convert1by1(AntShares.VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThanOrEqual(System.Numerics.BigInteger,System.Int64)") { _Convert1by1(AntShares.VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThan(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_GreaterThan(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.GT, src, to); return(0); } else { if (IsOpCall(refs, out callname)) { if (callname == "CHECKSIG") { callcode = VM.OpCode.CHECKSIG; calltype = 2; } } if (IsSysCall(refs, out callname)) { calltype = 3; } } } if (calltype == 0) { throw new Exception("unknown call:" + src.tokenMethod); } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _Insert1(VM.OpCode.PUSHDATA1, "swap 0 and 2 param", to, int2Pushdata1bytes(2)); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _Insert1(VM.OpCode.PUSHDATA1, "load" + saveto, to, int2Pushdata1bytes(saveto)); _Insert1(VM.OpCode.PICK, "", to); _Insert1(VM.OpCode.PUSHDATA1, "load" + i + 1, to, int2Pushdata1bytes(i + 1)); _Insert1(VM.OpCode.PICK, "", to); _Insert1(VM.OpCode.PUSHDATA1, "save to" + saveto + 2, to, int2Pushdata1bytes(saveto + 2)); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _Insert1(VM.OpCode.PUSHDATA1, "save to" + i + 1, to, int2Pushdata1bytes(i + 1)); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } if (calltype == 1) { var c = _Convert1by1(AntShares.VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfix = true; c.srcfunc = src.tokenMethod; return(0); } else if (calltype == 2) { _Convert1by1(callcode, null, to); return(0); } else if (calltype == 3) { _Convert1by1(AntShares.VM.OpCode.SYSCALL, null, to, str2Pushdata1bytes(callname)); return(0); } return(0); }
private int _ConvertCall(OpCode src, NeoMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; int callpcount = 0; byte[] callhash = null; VM.OpCode callcode = VM.OpCode.NOP; Mono.Cecil.MethodDefinition defs = null; try { defs = refs.Resolve(); } catch { } if (IsNonCall(defs)) { return(0); } else if (IsNotifyCall(defs, refs, to, out callname)) { calltype = 5; } else if (to.lastparam >= 0) { callpcount = to.lastparam; calltype = 6; to.lastparam = -1; } else if (IsOpCall(defs, out callname)) { if (System.Enum.TryParse <VM.OpCode>(callname, out callcode)) { calltype = 2; } else { throw new Exception("Can not find OpCall:" + callname); } } else if (IsSysCall(defs, out callname)) { calltype = 3; } else if (IsAppCall(defs, out callhash)) { calltype = 4; } else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else {//maybe a syscall // or other if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit(")) { //各类显示隐示转换都忽略 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Int64 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } return(0); } else if (src.tokenMethod == "System.Void System.Diagnostics.Debugger::Break()") { _Convert1by1(VM.OpCode.NOP, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals(")) { var _ref = src.tokenUnknown as Mono.Cecil.MethodReference; if (_ref.DeclaringType.FullName == "System.Boolean" || _ref.DeclaringType.FullName == "System.Int32" || _ref.DeclaringType.FullName == "System.Numerics.BigInteger") { _Convert1by1(VM.OpCode.NUMEQUAL, src, to); } else { _Convert1by1(VM.OpCode.EQUAL, src, to); } //各类==指令 //有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)") //{ // _Convert1by1(VM.OpCode.EQUAL, src, to); // return 0; //} //else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") //{ // _Convert1by1(VM.OpCode.EQUAL, src, to); // return 0; //} //_Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Inequality(")) { var _ref = src.tokenUnknown as Mono.Cecil.MethodReference; if (_ref.DeclaringType.FullName == "System.Boolean" || _ref.DeclaringType.FullName == "System.Int32" || _ref.DeclaringType.FullName == "System.Numerics.BigInteger") { _Convert1by1(VM.OpCode.NUMNOTEQUAL, src, to); } else { _Convert1by1(VM.OpCode.EQUAL, src, to); _Convert1by1(VM.OpCode.NOT, null, to); } ////各类!=指令 ////有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)") //{ // _Convert1by1(VM.OpCode.INVERT, src, to); // _Insert1(VM.OpCode.EQUAL, "", to); // return 0; //} //_Convert1by1(VM.OpCode.INVERT, src, to); //_Insert1(VM.OpCode.EQUAL, "", to); return(0); } else if (src.tokenMethod.Contains("::op_Addition(")) { //各类+指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.ADD, src, to); return(0); } _Convert1by1(VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Subtraction(")) { //各类-指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.SUB, src, to); return(0); } _Convert1by1(VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Multiply(")) { //各类*指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MUL, src, to); return(0); } _Convert1by1(VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Division(")) { //各类/指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Division(System.Numerics.BigInteger, System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.DIV, src, to); return(0); } _Convert1by1(VM.OpCode.DIV, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Modulus(")) { //各类%指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Modulus(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MOD, src, to); return(0); } _Convert1by1(VM.OpCode.MOD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThan(")) { //各类<指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThan(")) { //各类>指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThanOrEqual(")) { //各类<=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual(")) { //各类>=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GTE, src, to); return(0); } else if (src.tokenMethod.Contains("::get_Length(")) { //各类.Length指令 //"System.Int32 System.String::get_Length()" _Convert1by1(VM.OpCode.SIZE, src, to); return(0); } else if (src.tokenMethod.Contains("::Concat(")) { //各类.Concat //"System.String System.String::Concat(System.String,System.String)" _Convert1by1(VM.OpCode.CAT, src, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)") { _Convert1by1(VM.OpCode.SUBSTR, src, to); return(0); } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { _ConvertPush(1, src, to); _Convert1by1(VM.OpCode.SUBSTR, null, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32)") { throw new Exception("neomachine cant use this call,please use .SubString(1,2) with 2 params."); } else if (src.tokenMethod == "System.String System.Char::ToString()") { return(0); } else if (src.tokenMethod == "System.Byte[] System.Numerics.BigInteger::ToByteArray()") { return(0); } else if (src.tokenMethod == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])") { _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); return(0); } else if (src.tokenMethod == "System.UInt32 <PrivateImplementationDetails>::ComputeStringHash(System.String)") { throw new Exception("not supported on neovm now."); // 需要neo.vm nuget更新以后,这个才可以放开,就可以处理 string switch了。"); //_Convert1by1(VM.OpCode.CSHARPSTRHASH32, src, to); //return 0; } else { } } if (calltype == 0) { //之前的所有尝试都无效,那也不一定是个不存在的函数,有可能在别的模块里 if (TryInsertMethod(outModule, defs)) { calltype = 1; //ILModule module = new ILModule(); //module.LoadModule //ILType type =new ILType() //ILMethod method = new ILMethod(defs) } else { throw new Exception("unknown call: " + src.tokenMethod + "\r\n in: " + to.name + "\r\n"); } } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; bool havethis = md.HasThis; if (calltype == 2) { //opcode call } else {//翻转参数顺序 //如果是syscall 并且有this的,翻转范围加一 if (calltype == 3 && havethis) { pcount++; } _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } } if (calltype == 1) { if (this.outModule.option.useNep8) { byte _pcount = (byte)defs.Parameters.Count; byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1); var c = _Convert1by1(VM.OpCode.CALL_I, null, to, new byte[] { _rvcount, _pcount, 0, 0 }); c.needfixfunc = true; c.srcfunc = src.tokenMethod; } else { var c = _Convert1by1(VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfixfunc = true; c.srcfunc = src.tokenMethod; } return(0); } else if (calltype == 2) { _Convert1by1(callcode, src, to); return(0); } else if (calltype == 3) { var bytes = Encoding.UTF8.GetBytes(callname); if (bytes.Length > 252) { throw new Exception("string is to long"); } byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { if (this.outModule.option.useNep8) { byte _pcount = (byte)defs.Parameters.Count; byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1); if (callhash.All(v => v == 0))//empty nep4 { throw new Exception("nep4 calltype==6"); } else { var bytes = new byte[] { _rvcount, _pcount }.Concat(callhash).ToArray(); _Convert1by1(VM.OpCode.CALL_E, null, to, bytes); } } else { _Convert1by1(VM.OpCode.APPCALL, null, to, callhash); } } else if (calltype == 5) { //把name参数推进去 var callp = Encoding.UTF8.GetBytes(callname); _ConvertPush(callp, src, to); //参数打包成array _ConvertPush(pcount + 1, null, to); _Convert1by1(VM.OpCode.PACK, null, to); //a syscall { var bytes = Encoding.UTF8.GetBytes("Neo.Runtime.Notify"); byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); } } else if (calltype == 6) { _ConvertPush(callpcount, src, to); _Convert1by1(VM.OpCode.ROLL, null, to); //dyn appcall if (this.outModule.option.useNep8) { byte _pcount = (byte)defs.Parameters.Count; byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1); //byte signature = (byte)( // (retcount << 7) // | // defs.Parameters.Count // ); _Convert1by1(VM.OpCode.CALL_ED, null, to, new byte[] { _rvcount, _pcount }); } else { byte[] nullhash = new byte[20]; _Convert1by1(VM.OpCode.APPCALL, null, to, nullhash); } } return(0); }
private int _ConvertCall(JavaMethod method, OpCode src, AntsMethod to) { _Convert1by1(VM.OpCode.NOP, src, to); var cc = method.DeclaringType.classfile.constantpool; var c = cc[src.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref; var name = c.Class + "::" + c.Name; List <string> paramTypes = new List <string>(); string returntype; JavaMethod.scanTypes(c.Signature, out returntype, paramTypes); JavaClass javaclass = null; JavaMethod _javamethod = null; if (this.srcModule.classes.ContainsKey(c.Class)) { javaclass = this.srcModule.classes[c.Class]; if (javaclass.methods.ContainsKey(c.Name)) { _javamethod = javaclass.methods[c.Name]; } else { while (javaclass != null) { if (this.srcModule.classes.ContainsKey(javaclass.superClass)) { javaclass = this.srcModule.classes[javaclass.superClass]; if (javaclass.methods.ContainsKey(c.Name)) { _javamethod = javaclass.methods[c.Name]; break; } } else { javaclass = null; } } } } int calltype = 0; string callname = ""; byte[] callhash = null; VM.OpCode callcode = VM.OpCode.NOP; if (IsOpCall(_javamethod, src, out callname)) { if (System.Enum.TryParse <VM.OpCode>(callname, out callcode)) { calltype = 2; } else { throw new Exception("Can not find OpCall:" + callname); } } else if (IsSysCall(_javamethod, src, out callname)) { calltype = 3; } else if (IsAppCall(_javamethod, src, out callhash)) { calltype = 4; } else if (this.outModule.mapMethods.ContainsKey(name)) {//this is a call calltype = 1; } else { if (name == "java.io.PrintStream::println") {//drop 1; Console.WriteLine("logstr."); _Convert1by1(VM.OpCode.DROP, src, to); return(0); } else if (name == "java.math.BigInteger::<init>") {//do nothing if (c.Signature == "([B)V") { return(0); } else if (c.Signature == "(Ljava/lang/String;)V") { throw new Exception("not support new BigInteger(string)"); } } else if (name == "java.math.BigInteger::add") { _Convert1by1(VM.OpCode.ADD, src, to); return(0); } else if (name == "java.math.BigInteger::subtract") { _Convert1by1(VM.OpCode.SUB, src, to); return(0); } else if (name == "java.math.BigInteger::multiply") { _Convert1by1(VM.OpCode.MUL, src, to); return(0); } else if (name == "java.math.BigInteger::divide") { _Convert1by1(VM.OpCode.DIV, src, to); return(0); } else if (name == "java.math.BigInteger::mod") { _Convert1by1(VM.OpCode.MOD, src, to); return(0); } else if (name == "java.math.BigInteger::compareTo") { //need parse _Convert1by1(VM.OpCode.SUB, src, to); _Convert1by1(VM.OpCode.SIGN, null, to); //_Convert1by1(VM.OpCode.DEC, src, to); return(0); } // todo: what about java.lang.String::contentEquals? else if (name == "java.math.BigInteger::equals" || name == "java.lang.String::equals" || name == "kotlin.jvm.internal.Intrinsics::areEqual") { _Convert1by1(VM.OpCode.NUMEQUAL, src, to); //_Convert1by1(VM.OpCode.DEC, src, to); return(0); } else if (name == "java.math.BigInteger::valueOf" || name == "java.math.BigInteger::intValue" || name == "java.lang.Boolean::valueOf" || name == "java.lang.Character::valueOf" || name == "java.lang.String::valueOf" || name == "java.lang.Long::valueOf" || name == "java.math.BigInteger::toByteArray") { //donothing return(0); } else if (name == "java.lang.Boolean::booleanValue") { _Convert1by1(VM.OpCode.NOP, src, to); return(0); } else if (name == "java.lang.String::hashCode") { //java switch 的编译方式很奇怪 return(0); } else if (name == "java.lang.String::charAt") { _ConvertPush(1, src, to); _Convert1by1(VM.OpCode.SUBSTR, null, to); return(0); } else if (name == "java.lang.String::length") { _Convert1by1(VM.OpCode.SIZE, null, to); return(0); } else if (c.Class == "java.lang.StringBuilder") { return(_ConvertStringBuilder(c.Name, null, to)); } else if (name == "java.util.Arrays::equals") { _Convert1by1(VM.OpCode.EQUAL, null, to); return(0); } else if (name == "kotlin.jvm.internal.Intrinsics::checkParameterIsNotNull") { _Convert1by1(VM.OpCode.DROP, null, to); _Convert1by1(VM.OpCode.DROP, null, to); return(0); } } if (calltype == 0) { throw new Exception("unknown call:" + name); } var pcount = paramTypes.Count; if (calltype == 2) { //opcode call } else {//翻转参数入栈顺序 _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } } if (calltype == 1) { var _c = _Convert1by1(VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); _c.needfix = true; _c.srcfunc = name; return(0); } else if (calltype == 2) { _Convert1by1(callcode, null, to); return(0); } else if (calltype == 3) { var bytes = Encoding.UTF8.GetBytes(callname); if (bytes.Length > 252) { throw new Exception("string is too long"); } byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { _Convert1by1(VM.OpCode.APPCALL, null, to, callhash); } return(0); }
private int _ConvertCall(OpCode src, AntsMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; VM.OpCode callcode = VM.OpCode.NOP; if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else if (refs.ReturnType.Name == "ExecutionEngine" || refs.ReturnType.Name == "Storage") { if (src != null) { //有可能jump到此处 this.addrconv[src.addr] = this.addr;//因为没插入代码,实际是下一行 } //donothing 語法過渡類型 return(0); } else {//maybe a syscall // or other if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals(")) { _Convert1by1(AntShares.VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThanOrEqual(System.Numerics.BigInteger,System.Int64)") { _Convert1by1(AntShares.VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThan(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_GreaterThan(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(AntShares.VM.OpCode.GT, src, to); return(0); } else { if (IsOpCall(refs, out callname)) { if (callname == "CHECKSIG") { callcode = VM.OpCode.CHECKSIG; calltype = 2; } } if (IsSysCall(refs, out callname)) { calltype = 3; } } } if (calltype == 0) { throw new Exception("unknown call:" + src.tokenMethod); } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } if (calltype == 1) { var c = _Convert1by1(AntShares.VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfix = true; c.srcfunc = src.tokenMethod; return(0); } else if (calltype == 2) { _Convert1by1(callcode, null, to); return(0); } else if (calltype == 3) { var bytes = Encoding.UTF8.GetBytes(callname); if (bytes.Length > 252) { throw new Exception("string is to long"); } byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(AntShares.VM.OpCode.SYSCALL, null, to, outbytes); return(0); } return(0); }
public virtual void SetParam(VM.OpCode opcode, byte[] opdata) { }
private int _ConvertCall(OpCode src, AntsMethod to) { Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference; int calltype = 0; string callname = ""; byte[] callhash = null; VM.OpCode callcode = VM.OpCode.NOP; Mono.Cecil.MethodDefinition defs = null; try { defs = refs.Resolve(); } catch { } if (IsNonCall(defs)) { return(0); } else if (IsOpCall(defs, out callname)) { if (System.Enum.TryParse <VM.OpCode>(callname, out callcode)) { calltype = 2; } else { throw new Exception("Can not find OpCall:" + callname); } } else if (IsSysCall(defs, out callname)) { calltype = 3; } else if (IsAppCall(defs, out callhash)) { calltype = 4; } else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod)) {//this is a call calltype = 1; } else {//maybe a syscall // or other if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit(")) { //各类显示隐示转换都忽略 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Int64 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)") { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber { //donothing return(0); } else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)") { return(0); } return(0); } else if (src.tokenMethod == "System.Void System.Diagnostics.Debugger::Break()") { _Convert1by1(VM.OpCode.NOP, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals(")) { //各类==指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)") { _Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") { _Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } _Convert1by1(VM.OpCode.EQUAL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Inequality(")) { //各类!=指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.INVERT, src, to); _Insert1(VM.OpCode.EQUAL, "", to); return(0); } _Convert1by1(VM.OpCode.INVERT, src, to); _Insert1(VM.OpCode.EQUAL, "", to); return(0); } else if (src.tokenMethod.Contains("::op_Addition(")) { //各类+指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.ADD, src, to); return(0); } _Convert1by1(VM.OpCode.ADD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Subtraction(")) { //各类-指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.SUB, src, to); return(0); } _Convert1by1(VM.OpCode.SUB, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Multiply(")) { //各类*指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MUL, src, to); return(0); } _Convert1by1(VM.OpCode.MUL, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Division(")) { //各类/指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Division(System.Numerics.BigInteger, System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.DIV, src, to); return(0); } _Convert1by1(VM.OpCode.DIV, src, to); return(0); } else if (src.tokenMethod.Contains("::op_Modulus(")) { //各类%指令 //有可能有一些会特殊处理,故还保留独立判断 if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Modulus(System.Numerics.BigInteger,System.Numerics.BigInteger)") { _Convert1by1(VM.OpCode.MOD, src, to); return(0); } _Convert1by1(VM.OpCode.MOD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThan(")) { //各类<指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThan(")) { //各类>指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThanOrEqual(")) { //各类<=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual(")) { //各类>=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(VM.OpCode.GTE, src, to); return(0); } else if (src.tokenMethod.Contains("::get_Length(")) { //各类.Length指令 //"System.Int32 System.String::get_Length()" _Convert1by1(VM.OpCode.SIZE, src, to); return(0); } else if (src.tokenMethod.Contains("::Concat(")) { //各类.Concat //"System.String System.String::Concat(System.String,System.String)" _Convert1by1(VM.OpCode.CAT, src, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)") { _Convert1by1(VM.OpCode.SUBSTR, src, to); return(0); } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { _ConvertPush(1, src, to); _Convert1by1(VM.OpCode.SUBSTR, null, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32)") { throw new Exception("antsmachine cant use this call,please use .SubString(1,2) with 2 params."); } else if (src.tokenMethod == "System.String System.Char::ToString()") { return(0); } else if (src.tokenMethod == "System.Byte[] System.Numerics.BigInteger::ToByteArray()") { return(0); } else if (src.tokenMethod == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])") { _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _ConvertPush(2, null, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); return(0); } else { } } if (calltype == 0) { throw new Exception("unknown call:" + src.tokenMethod); } var md = src.tokenUnknown as Mono.Cecil.MethodReference; var pcount = md.Parameters.Count; _Convert1by1(VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(VM.OpCode.XSWAP, "", to); _Insert1(VM.OpCode.DROP, "", to); } } if (calltype == 1) { var c = _Convert1by1(VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); c.needfix = true; c.srcfunc = src.tokenMethod; return(0); } else if (calltype == 2) { _Convert1by1(callcode, null, to); return(0); } else if (calltype == 3) { var bytes = Encoding.UTF8.GetBytes(callname); if (bytes.Length > 252) { throw new Exception("string is to long"); } byte[] outbytes = new byte[bytes.Length + 1]; outbytes[0] = (byte)bytes.Length; Array.Copy(bytes, 0, outbytes, 1, bytes.Length); //bytes.Prepend 函数在 dotnet framework 4.6 编译不过 _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { _Convert1by1(VM.OpCode.APPCALL, null, to, callhash); } return(0); }