Beispiel #1
0
        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);
        }
Beispiel #3
0
        public void SetParam(VM.OpCode _op, byte[] data)
        {
            var op = curScript.ops.Last();

            if (op.op == _op)
            {
                op.opparam = data;
            }
        }
Beispiel #4
0
 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);
     }
 }
Beispiel #5
0
 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);
 }
Beispiel #6
0
        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);
        }
Beispiel #7
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);
 }
Beispiel #11
0
        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);
        }
Beispiel #12
0
 public LogOp(int addr, VM.OpCode op)
 {
     this.addr = addr;
     this.op   = op;
 }
Beispiel #13
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")
            {
                //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);
        }
Beispiel #14
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);
        }
Beispiel #15
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);
        }
Beispiel #16
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);
        }
Beispiel #17
0
 public virtual void SetParam(VM.OpCode opcode, byte[] opdata)
 {
 }
Beispiel #18
0
        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);
        }