private NeoCode _Convert1by1(Lux.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); }
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(Lux.VM.OpCode.NOP, src, to);//空白 var pcount = _type.Parameters.Count; for (var i = 0; i < pcount; i++) { _Insert1(Lux.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; Lux.VM.OpCode v = (Lux.VM.OpCode)value; _Insert1(v, null, to); return(0); } } } } _Convert1by1(Lux.VM.OpCode.NOP, src, to); //空白 _ConvertPush(type.DeclaringType.Fields.Count, null, to); //插入个数量 if (type.DeclaringType.IsValueType) { _Insert1(Lux.VM.OpCode.NEWSTRUCT, null, to); } else { _Insert1(Lux.VM.OpCode.NEWARRAY, null, to); } return(0); }
private NeoCode _Insert1(Lux.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); }
private int ConvertCode(ILMethod method, OpCode src, NeoMethod to) { int skipcount = 0; switch (src.code) { case CodeEx.Nop: _Convert1by1(Lux.VM.OpCode.NOP, src, to); break; case CodeEx.Ret: //return 在外面特殊处理了 _Insert1(Lux.VM.OpCode.RET, null, to); break; case CodeEx.Pop: _Convert1by1(Lux.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(Lux.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(Lux.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(Lux.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(Lux.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(Lux.VM.OpCode.NUMEQUAL, src, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.ABS, src, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.ABS, null, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.NUMNOTEQUAL, null, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.LT, src, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.ABS, src, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.ABS, null, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.LT, null, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.LTE, src, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.ABS, src, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.ABS, null, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.LTE, null, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.GT, src, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.ABS, src, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.ABS, null, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.GT, null, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.GTE, src, to); var code = _Convert1by1(Lux.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(Lux.VM.OpCode.ABS, src, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.ABS, null, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.GTE, null, to); var code = _Convert1by1(Lux.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 }); code.needfix = true; code.srcaddr = src.tokenAddr_Index; } break; //Stack case CodeEx.Dup: _Convert1by1(Lux.VM.OpCode.DUP, src, to); break; //Bitwise logic case CodeEx.And: _Convert1by1(Lux.VM.OpCode.AND, src, to); break; case CodeEx.Or: _Convert1by1(Lux.VM.OpCode.OR, src, to); break; case CodeEx.Xor: _Convert1by1(Lux.VM.OpCode.XOR, src, to); break; case CodeEx.Not: _Convert1by1(Lux.VM.OpCode.INVERT, src, to); break; //math case CodeEx.Add: case CodeEx.Add_Ovf: case CodeEx.Add_Ovf_Un: _Convert1by1(Lux.VM.OpCode.ADD, src, to); break; case CodeEx.Sub: case CodeEx.Sub_Ovf: case CodeEx.Sub_Ovf_Un: _Convert1by1(Lux.VM.OpCode.SUB, src, to); break; case CodeEx.Mul: case CodeEx.Mul_Ovf: case CodeEx.Mul_Ovf_Un: _Convert1by1(Lux.VM.OpCode.MUL, src, to); break; case CodeEx.Div: case CodeEx.Div_Un: _Convert1by1(Lux.VM.OpCode.DIV, src, to); break; case CodeEx.Rem: case CodeEx.Rem_Un: _Convert1by1(Lux.VM.OpCode.MOD, src, to); break; case CodeEx.Neg: _Convert1by1(Lux.VM.OpCode.NEGATE, src, to); break; case CodeEx.Shl: _Convert1by1(Lux.VM.OpCode.SHL, src, to); break; case CodeEx.Shr: case CodeEx.Shr_Un: _Convert1by1(Lux.VM.OpCode.SHR, src, to); break; //logic case CodeEx.Clt: case CodeEx.Clt_Un: _Convert1by1(Lux.VM.OpCode.LT, src, to); break; case CodeEx.Cgt: case CodeEx.Cgt_Un: _Convert1by1(Lux.VM.OpCode.GT, src, to); break; case CodeEx.Ceq: _Convert1by1(Lux.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: _ConvertPush(1, src, to); _Convert1by1(Lux.VM.OpCode.SUBSTR, null, to); break; //用意为sbyte[] 取一部分..... // en: intent to use sbyte[] as array..... case CodeEx.Ldelem_I1: _ConvertPush(1, src, to); _Convert1by1(Lux.VM.OpCode.SUBSTR, null, to); break; 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(Lux.VM.OpCode.PICKITEM, src, to); break; case CodeEx.Ldlen: _Convert1by1(Lux.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 == Lux.VM.OpCode.PICKITEM) && (to.body_Codes[addr - 4].code == Lux.VM.OpCode.PICKITEM) && (to.body_Codes[addr - 7].code == Lux.VM.OpCode.PICKITEM) && (to.body_Codes[addr - 3].code == Lux.VM.OpCode.DUPFROMALTSTACK) && (to.body_Codes[addr - 6].code == Lux.VM.OpCode.DUPFROMALTSTACK) && (to.body_Codes[addr - 9].code == Lux.VM.OpCode.DUPFROMALTSTACK) && ((to.body_Codes[addr - 2].code >= Lux.VM.OpCode.PUSH0) && (to.body_Codes[addr - 2].code <= Lux.VM.OpCode.PUSH16)) && ((to.body_Codes[addr - 5].code >= Lux.VM.OpCode.PUSH0) && (to.body_Codes[addr - 5].code <= Lux.VM.OpCode.PUSH16)) && ((to.body_Codes[addr - 8].code >= Lux.VM.OpCode.PUSH0) && (to.body_Codes[addr - 8].code <= Lux.VM.OpCode.PUSH16)) ) { // WILL REQUIRE TO PROCESS INFORMATION AND STORE IT AGAIN ON ALTSTACK CORRECT POSITION Lux.VM.OpCode PushZ = to.body_Codes[addr - 8].code; _Convert1by1(Lux.VM.OpCode.PUSH2, null, to); _Convert1by1(Lux.VM.OpCode.PICK, null, to); _Convert1by1(Lux.VM.OpCode.PUSH2, null, to); _Convert1by1(Lux.VM.OpCode.PICK, null, to); _Convert1by1(Lux.VM.OpCode.LEFT, null, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.CAT, null, to); _Convert1by1(Lux.VM.OpCode.ROT, null, to); _Convert1by1(Lux.VM.OpCode.ROT, null, to); _Convert1by1(Lux.VM.OpCode.OVER, null, to); _Convert1by1(Lux.VM.OpCode.ARRAYSIZE, null, to); _Convert1by1(Lux.VM.OpCode.DEC, null, to); _Convert1by1(Lux.VM.OpCode.SWAP, null, to); _Convert1by1(Lux.VM.OpCode.SUB, null, to); _Convert1by1(Lux.VM.OpCode.RIGHT, null, to); _Convert1by1(Lux.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(Lux.VM.OpCode.DUPFROMALTSTACK, null, to); // stack: [ array , result , ... ] _Convert1by1(PushZ, null, to); // stack: [ pushz, array , result , ... ] _Convert1by1(Lux.VM.OpCode.ROT, null, to); // stack: [ result, pushz, array , ... ] _Convert1by1(Lux.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(Lux.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(Lux.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(Lux.VM.OpCode.THROW, src, to); //throw 会让vm 挂起 //不需要再插入return //_Insert1(Lux.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 OpCodeAttribute(Lux.VM.OpCode opcode) { this.OpCode = opcode; }
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; Lux.VM.OpCode callcode = Lux.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 <Lux.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(Lux.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(Lux.VM.OpCode.NUMEQUAL, src, to); } else { _Convert1by1(Lux.VM.OpCode.EQUAL, src, to); } //各类==指令 //有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)") //{ // _Convert1by1(Lux.VM.OpCode.EQUAL, src, to); // return 0; //} //else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") //{ // _Convert1by1(Lux.VM.OpCode.EQUAL, src, to); // return 0; //} //_Convert1by1(Lux.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(Lux.VM.OpCode.NUMNOTEQUAL, src, to); } else { _Convert1by1(Lux.VM.OpCode.INVERT, src, to); _Insert1(Lux.VM.OpCode.EQUAL, "", to); } ////各类!=指令 ////有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)") //{ // _Convert1by1(Lux.VM.OpCode.INVERT, src, to); // _Insert1(Lux.VM.OpCode.EQUAL, "", to); // return 0; //} //_Convert1by1(Lux.VM.OpCode.INVERT, src, to); //_Insert1(Lux.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(Lux.VM.OpCode.ADD, src, to); return(0); } _Convert1by1(Lux.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(Lux.VM.OpCode.SUB, src, to); return(0); } _Convert1by1(Lux.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(Lux.VM.OpCode.MUL, src, to); return(0); } _Convert1by1(Lux.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(Lux.VM.OpCode.DIV, src, to); return(0); } _Convert1by1(Lux.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(Lux.VM.OpCode.MOD, src, to); return(0); } _Convert1by1(Lux.VM.OpCode.MOD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThan(")) { //各类<指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(Lux.VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThan(")) { //各类>指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(Lux.VM.OpCode.GT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThanOrEqual(")) { //各类<=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(Lux.VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual(")) { //各类>=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(Lux.VM.OpCode.GTE, src, to); return(0); } else if (src.tokenMethod.Contains("::get_Length(")) { //各类.Length指令 //"System.Int32 System.String::get_Length()" _Convert1by1(Lux.VM.OpCode.SIZE, src, to); return(0); } else if (src.tokenMethod.Contains("::Concat(")) { //各类.Concat //"System.String System.String::Concat(System.String,System.String)" _Convert1by1(Lux.VM.OpCode.CAT, src, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)") { _Convert1by1(Lux.VM.OpCode.SUBSTR, src, to); return(0); } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { _ConvertPush(1, src, to); _Convert1by1(Lux.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(Lux.VM.OpCode.DUPFROMALTSTACK, src, to); _ConvertPush(2, null, to); _Convert1by1(Lux.VM.OpCode.ROLL, null, to); _ConvertPush(2, null, to); _Convert1by1(Lux.VM.OpCode.ROLL, null, to); _Convert1by1(Lux.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(Lux.VM.OpCode.CSHARPSTRHASH32, src, to); //return 0; } else { } } if (calltype == 0) { 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(Lux.VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(Lux.VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(Lux.VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(Lux.VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(Lux.VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(Lux.VM.OpCode.XSWAP, "", to); _Insert1(Lux.VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(Lux.VM.OpCode.XSWAP, "", to); _Insert1(Lux.VM.OpCode.DROP, "", to); } } } if (calltype == 1) { var c = _Convert1by1(Lux.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(Lux.VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { _Convert1by1(Lux.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(Lux.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(Lux.VM.OpCode.SYSCALL, null, to, outbytes); } } else if (calltype == 6) { _ConvertPush(callpcount, src, to); _Convert1by1(Lux.VM.OpCode.ROLL, null, to); byte[] nullhash = new byte[20]; //dyn appcall _Convert1by1(Lux.VM.OpCode.APPCALL, null, to, nullhash); } return(0); }