Beispiel #1
0
        private void _ConvertLdLocA(ILMethod method, OpCode src, BhpMethod to, int pos)
        {//这有两种情况,我们需要先判断这个引用地址是拿出来干嘛的
            var n1 = method.body_Codes[method.GetNextCodeAddr(src.addr)];
            var n2 = method.body_Codes[method.GetNextCodeAddr(n1.addr)];

            if (n1.code == CodeEx.Initobj)//初始化结构体,必须给引用地址
            {
                _ConvertPush(pos + method.paramtypes.Count, src, to);
            }
            else if (n2.code == CodeEx.Call && n2.tokenMethod.Contains(".ctor"))
            {
                _ConvertPush(pos + method.paramtypes.Count, src, to);
            }
            else
            {
                _ConvertLdLoc(method, src, to, pos);
            }
        }
Beispiel #2
0
        private int _ConvertPushI8WithConv(ILMethod from, long i, OpCode src, BhpMethod to)
        {
            var        next = from.GetNextCodeAddr(src.addr);
            var        code = from.body_Codes[next].code;
            BigInteger outv;

            if (code == CodeEx.Conv_U || code == CodeEx.Conv_U8)
            //code == CodeEx.Conv_U1 || code ==CodeEx.Conv_U2 || code==CodeEx.Conv_U4|| code== CodeEx.Conv_U8)
            {
                ulong v = (ulong)i;
                outv = v;
                _ConvertPush(outv.ToByteArray(), src, to);
                return(1);
            }
            else if (code == CodeEx.Conv_U1)
            {
                byte v = (byte)i;
                outv = v;
                _ConvertPush(outv.ToByteArray(), src, to);
                return(1);
            }
            else if (code == CodeEx.Conv_U2)
            {
                ushort v = (ushort)i;
                outv = v;
                _ConvertPush(outv.ToByteArray(), src, to);
                return(1);
            }
            else if (code == CodeEx.Conv_U4)
            {
                uint v = (uint)i;
                outv = v;
                _ConvertPush(outv.ToByteArray(), src, to);
                return(1);
            }
            else if (code == CodeEx.Call)
            {
                var call = from.body_Codes[next];
                if (call.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.UInt64)")
                {//如果是ulong转型到biginteger,需要注意
                    ulong v = (ulong)i;
                    outv = v;
                    _ConvertPush(outv.ToByteArray(), src, to);
                    return(1);
                }
            }


            {
                _ConvertPush(i, src, to);
                return(0);
            }
        }
Beispiel #3
0
        private int _ConvertPushI4WithConv(ILMethod from, int i, OpCode src, BhpMethod to)
        {
            var        next = from.GetNextCodeAddr(src.addr);
            var        code = from.body_Codes[next].code;
            BigInteger outv;

            if (code == CodeEx.Conv_U || code == CodeEx.Conv_U8)
            //code == CodeEx.Conv_U1 || code ==CodeEx.Conv_U2 || code==CodeEx.Conv_U4|| code== CodeEx.Conv_U8)
            {
                ulong v = (uint)i;
                outv = v;
                _ConvertPush(outv.ToByteArray(), src, to);
                return(1);
            }
            else if (code == CodeEx.Conv_U1)
            {
                byte v = (byte)i;
                outv = v;
                _ConvertPush(outv.ToByteArray(), src, to);
                return(1);
            }
            else if (code == CodeEx.Conv_U2)
            {
                ushort v = (ushort)i;
                outv = v;
                _ConvertPush(outv.ToByteArray(), src, to);
                return(1);
            }
            else if (code == CodeEx.Conv_U4)
            {
                uint v = (uint)i;
                outv = v;
                _ConvertPush(outv.ToByteArray(), src, to);
                return(1);
            }
            else
            {
                _ConvertPush(i, src, to);
                return(0);
            }
        }
Beispiel #4
0
        private int _ConvertNewArr(ILMethod method, OpCode src, BhpMethod to)
        {
            var type = src.tokenType;

            if (type != "System.Byte")
            {
                _Convert1by1(VM.OpCode.NEWARRAY, src, to);
                int n  = method.GetNextCodeAddr(src.addr);
                int n2 = method.GetNextCodeAddr(n);
                int n3 = method.GetNextCodeAddr(n2);
                if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call)
                {//這是在初始化數組
                    var data = method.body_Codes[n2].tokenUnknown as byte[];
                    if (type == "System.Char")
                    {
                        for (var i = 0; i < data.Length; i += 2)
                        {
                            char info = BitConverter.ToChar(data, i);
                            _Convert1by1(VM.OpCode.DUP, null, to);
                            _ConvertPush(i / 2, null, to);
                            _ConvertPush(info, null, to);
                            _Convert1by1(VM.OpCode.SETITEM, null, to);
                        }
                        return(3);
                    }
                    throw new Exception("not support this type's init array.");
                }
                return(0);
                //this.logger.Log("_ConvertNewArr::not support type " + type + " for array.");
            }
            else
            {
                var code = to.body_Codes.Last().Value;
                //we need a number
                if (code.code > VM.OpCode.PUSH16)
                {
                    throw new Exception("_ConvertNewArr::not support var lens for new byte[?].");
                }
                var number = getNumber(code);

                //移除上一条指令
                to.body_Codes.Remove(code.addr);
                this.addr = code.addr;

                //new array 指令處理有問題,這個addr 已經包括了data
                //if (code.bytes != null)
                //    this.addr -= code.bytes.Length;

                int n  = method.GetNextCodeAddr(src.addr);
                int n2 = method.GetNextCodeAddr(n);
                int n3 = method.GetNextCodeAddr(n2);
                int n4 = method.GetNextCodeAddr(n3);
                if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call)
                {//這是在初始化數組
                    var data = method.body_Codes[n2].tokenUnknown as byte[];
                    this._ConvertPush(data, src, to);

                    return(3);
                }
                else
                {
                    var outbyte = new byte[number];
                    var skip    = 0;
                    int start   = n;
                    System.Collections.Generic.Stack <int> stack = new System.Collections.Generic.Stack <int>();
                    var _code = method.body_Codes[start];
                    if (_code.code == CodeEx.Dup)//生成的setlem代码用dup
                    {
                        while (true)
                        {
                            int start2 = method.GetNextCodeAddr(start);
                            int start3 = method.GetNextCodeAddr(start2);
                            int start4 = method.GetNextCodeAddr(start3);
                            if (start < 0 || start2 < 0 || start3 < 0 || start4 < 0)
                            {
                                break;
                            }

                            _code = method.body_Codes[start];
                            var _code2 = method.body_Codes[start2];
                            var _code3 = method.body_Codes[start3];
                            var _code4 = method.body_Codes[start4];
                            if (_code.code != CodeEx.Dup || (_code4.code != CodeEx.Stelem_I1 && _code4.code != CodeEx.Stelem_I))
                            {
                                break;
                            }
                            else
                            {
                                var pos   = _code2.tokenI32;
                                var value = _code3.tokenI32;
                                outbyte[pos] = (byte)value;

                                skip += 4;
                                start = method.GetNextCodeAddr(start4);
                            }
                        }
                    }
                    else if ((_code.code == CodeEx.Stloc || _code.code == CodeEx.Stloc_0 || _code.code == CodeEx.Stloc_1 || _code.code == CodeEx.Stloc_2 || _code.code == CodeEx.Stloc_3 || _code.code == CodeEx.Stloc_S))
                    {
                        skip++;
                        start = method.GetNextCodeAddr(start);
                        _code = method.body_Codes[start];
                        bool bLdLoc = (_code.code == CodeEx.Ldloc || _code.code == CodeEx.Ldloc_0 || _code.code == CodeEx.Ldloc_1 || _code.code == CodeEx.Ldloc_2 || _code.code == CodeEx.Ldloc_3 || _code.code == CodeEx.Ldloc_S);
                        if (bLdLoc == false)//说明根本没有初始化的意思
                        {
                            this._ConvertPush(outbyte, src, to);
                            return(0);
                        }
                        while (true)
                        {
                            int start2 = method.GetNextCodeAddr(start);
                            int start3 = method.GetNextCodeAddr(start2);
                            int start4 = method.GetNextCodeAddr(start3);
                            if (start < 0 || start2 < 0 || start3 < 0 || start4 < 0)
                            {
                                break;
                            }
                            _code = method.body_Codes[start];
                            var _code2 = method.body_Codes[start2];
                            var _code3 = method.body_Codes[start3];
                            var _code4 = method.body_Codes[start4];
                            bLdLoc = (_code.code == CodeEx.Ldloc || _code.code == CodeEx.Ldloc_0 || _code.code == CodeEx.Ldloc_1 || _code.code == CodeEx.Ldloc_2 || _code.code == CodeEx.Ldloc_3 || _code.code == CodeEx.Ldloc_S);
                            bool bStelem = (_code4.code == CodeEx.Stelem_I1 || _code4.code == CodeEx.Stelem_I);
                            if (bLdLoc && bStelem)
                            {
                                var pos   = _code2.tokenI32;
                                var value = _code3.tokenI32;
                                outbyte[pos] = (byte)value;

                                skip += 4;
                                start = method.GetNextCodeAddr(start4);
                            }
                            else if (bLdLoc && !bStelem)
                            {
                                //走到这里说明不是预测的数组初始化,少处理了一种情况
                                this._ConvertPush(outbyte, src, to);
                                //就有两种情况
                                if (skip == 1)
                                {
                                    return(0);//没有初始化,那么第一个stloc 是不能跳过的
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    //有时c#也会用填数值的方式初始化,对于byte这会出错

                    this._ConvertPush(outbyte, src, to);
                    return(skip);
                }
            }
        }