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);
        }
示例#4
0
        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);
        }
示例#5
0
 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);
        }