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); } }
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); } }
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); } }
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); } } }