private QurasCode _Convert1by1(Pure.VM.OpCode code, OpCode src, NeoMethod to, byte[] data = null) { QurasCode _code = new QurasCode(); 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(Pure.VM.OpCode.NOP, src, to);//空白 var pcount = _type.Parameters.Count; for (var i = 0; i < pcount; i++) { _Insert1(Pure.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; Pure.VM.OpCode v = (Pure.VM.OpCode)value; _Insert1(v, null, to); return(0); } } } } _Convert1by1(Pure.VM.OpCode.NOP, src, to); //空白 _ConvertPush(type.DeclaringType.Fields.Count, null, to); //插入个数量 if (type.DeclaringType.IsValueType) { _Insert1(Pure.VM.OpCode.NEWSTRUCT, null, to); } else { _Insert1(Pure.VM.OpCode.NEWARRAY, null, to); } return(0); }
private QurasCode _Insert1(Pure.VM.OpCode code, string comment, NeoMethod to, byte[] data = null) { QurasCode _code = new QurasCode(); int startaddr = addr; _code.addr = addr; { _code.debugcode = comment; _code.debugline = 0; } addr++; _code.code = code; if (data != null) { _code.bytes = data; addr += _code.bytes.Length; } to.body_Codes[startaddr] = _code; return(_code); }
private int _ConvertCall(JavaMethod method, OpCode src, NeoMethod to) { _Convert1by1(Pure.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 + c.Signature)) { _javamethod = javaclass.methods[c.Name + c.Signature]; } else { while (javaclass != null) { if (this.srcModule.classes.ContainsKey(javaclass.superClass)) { javaclass = this.srcModule.classes[javaclass.superClass]; if (javaclass.methods.ContainsKey(c.Name + c.Signature)) { _javamethod = javaclass.methods[c.Name + c.Signature]; break; } } else { javaclass = null; } } } } int calltype = 0; string callname = ""; byte[] callhash = null; Pure.VM.OpCode callcode = Pure.VM.OpCode.NOP; if (IsNonCall(_javamethod)) { return(0); } else if (IsOpCall(_javamethod, src, out callname)) { if (System.Enum.TryParse <Pure.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(c.Class + "::" + c.Name + c.Signature)) {//this is a call calltype = 1; } else { if (name == "java.io.PrintStream::println") {//drop 1; Console.WriteLine("logstr."); _Convert1by1(Pure.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(Pure.VM.OpCode.ADD, src, to); return(0); } else if (name == "java.math.BigInteger::subtract") { _Convert1by1(Pure.VM.OpCode.SUB, src, to); return(0); } else if (name == "java.math.BigInteger::multiply") { _Convert1by1(Pure.VM.OpCode.MUL, src, to); return(0); } else if (name == "java.math.BigInteger::divide") { _Convert1by1(Pure.VM.OpCode.DIV, src, to); return(0); } else if (name == "java.math.BigInteger::mod") { _Convert1by1(Pure.VM.OpCode.MOD, src, to); return(0); } else if (name == "java.math.BigInteger::compareTo") { //need parse _Convert1by1(Pure.VM.OpCode.SUB, src, to); _Convert1by1(Pure.VM.OpCode.SIGN, null, to); //_Convert1by1(Pure.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(Pure.VM.OpCode.NUMEQUAL, src, to); //_Convert1by1(Pure.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.lang.Integer::valueOf" || name == "java.lang.Byte::valueOf" || name == "java.math.BigInteger::toByteArray") { //donothing return(0); } else if (name == "java.lang.Boolean::booleanValue" || name == "java.lang.Integer::integerValue" || name == "java.lang.Long::longValue" || name == "java.math.BigInteger::longValue") { _Convert1by1(Pure.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(Pure.VM.OpCode.SUBSTR, null, to); return(0); } else if (name == "java.lang.String::length") { _Convert1by1(Pure.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" || name == "kotlin.jvm.internal.Intrinsics::areEqual") { _Convert1by1(Pure.VM.OpCode.EQUAL, null, to); return(0); } else if (name == "kotlin.jvm.internal.Intrinsics::checkParameterIsNotNull") { _Convert1by1(Pure.VM.OpCode.DROP, null, to); _Convert1by1(Pure.VM.OpCode.DROP, null, to); return(0); } else if (name == "kotlin.jvm.internal.Intrinsics::throwNpe") { _Convert1by1(Pure.VM.OpCode.THROW, src, to); return(0); } } if (calltype == 0) { throw new Exception("unknown call:" + name); } var pcount = paramTypes.Count; if (calltype == 2) { //opcode call } else {//翻转参数入栈顺序 _Convert1by1(Pure.VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(Pure.VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(Pure.VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(Pure.VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(Pure.VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(Pure.VM.OpCode.XSWAP, "", to); _Insert1(Pure.VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(Pure.VM.OpCode.XSWAP, "", to); _Insert1(Pure.VM.OpCode.DROP, "", to); } } } if (calltype == 1) { var _c = _Convert1by1(Pure.VM.OpCode.CALL, null, to, new byte[] { 5, 0 }); _c.needfixfunc = true; _c.srcfunc = name + c.Signature; 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(Pure.VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { _Convert1by1(Pure.VM.OpCode.APPCALL, null, to, callhash); } return(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; Pure.VM.OpCode callcode = Pure.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 <Pure.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(Pure.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(Pure.VM.OpCode.NUMEQUAL, src, to); } else { _Convert1by1(Pure.VM.OpCode.EQUAL, src, to); } //各类==指令 //有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)") //{ // _Convert1by1(Pure.VM.OpCode.EQUAL, src, to); // return 0; //} //else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)") //{ // _Convert1by1(Pure.VM.OpCode.EQUAL, src, to); // return 0; //} //_Convert1by1(Pure.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(Pure.VM.OpCode.NUMNOTEQUAL, src, to); } else { _Convert1by1(Pure.VM.OpCode.INVERT, src, to); _Insert1(Pure.VM.OpCode.EQUAL, "", to); } ////各类!=指令 ////有可能有一些会特殊处理,故还保留独立判断 //if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)") //{ // _Convert1by1(Pure.VM.OpCode.INVERT, src, to); // _Insert1(Pure.VM.OpCode.EQUAL, "", to); // return 0; //} //_Convert1by1(Pure.VM.OpCode.INVERT, src, to); //_Insert1(Pure.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(Pure.VM.OpCode.ADD, src, to); return(0); } _Convert1by1(Pure.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(Pure.VM.OpCode.SUB, src, to); return(0); } _Convert1by1(Pure.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(Pure.VM.OpCode.MUL, src, to); return(0); } _Convert1by1(Pure.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(Pure.VM.OpCode.DIV, src, to); return(0); } _Convert1by1(Pure.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(Pure.VM.OpCode.MOD, src, to); return(0); } _Convert1by1(Pure.VM.OpCode.MOD, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThan(")) { //各类<指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(Pure.VM.OpCode.LT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThan(")) { //各类>指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(Pure.VM.OpCode.GT, src, to); return(0); } else if (src.tokenMethod.Contains("::op_LessThanOrEqual(")) { //各类<=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(Pure.VM.OpCode.LTE, src, to); return(0); } else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual(")) { //各类>=指令 //有可能有一些会特殊处理,故还保留独立判断 _Convert1by1(Pure.VM.OpCode.GTE, src, to); return(0); } else if (src.tokenMethod.Contains("::get_Length(")) { //各类.Length指令 //"System.Int32 System.String::get_Length()" _Convert1by1(Pure.VM.OpCode.SIZE, src, to); return(0); } else if (src.tokenMethod.Contains("::Concat(")) { //各类.Concat //"System.String System.String::Concat(System.String,System.String)" _Convert1by1(Pure.VM.OpCode.CAT, src, to); return(0); } else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)") { _Convert1by1(Pure.VM.OpCode.SUBSTR, src, to); return(0); } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { _ConvertPush(1, src, to); _Convert1by1(Pure.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(Pure.VM.OpCode.DUPFROMALTSTACK, src, to); _ConvertPush(2, null, to); _Convert1by1(Pure.VM.OpCode.ROLL, null, to); _ConvertPush(2, null, to); _Convert1by1(Pure.VM.OpCode.ROLL, null, to); _Convert1by1(Pure.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(Pure.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(Pure.VM.OpCode.NOP, src, to); if (pcount <= 1) { } else if (pcount == 2) { _Insert1(Pure.VM.OpCode.SWAP, "swap 2 param", to); } else if (pcount == 3) { _InsertPush(2, "swap 0 and 2 param", to); _Insert1(Pure.VM.OpCode.XSWAP, "", to); } else { for (var i = 0; i < pcount / 2; i++) { int saveto = (pcount - 1 - i); _InsertPush(saveto, "load" + saveto, to); _Insert1(Pure.VM.OpCode.PICK, "", to); _InsertPush(i + 1, "load" + i + 1, to); _Insert1(Pure.VM.OpCode.PICK, "", to); _InsertPush(saveto + 2, "save to" + saveto + 2, to); _Insert1(Pure.VM.OpCode.XSWAP, "", to); _Insert1(Pure.VM.OpCode.DROP, "", to); _InsertPush(i + 1, "save to" + i + 1, to); _Insert1(Pure.VM.OpCode.XSWAP, "", to); _Insert1(Pure.VM.OpCode.DROP, "", to); } } } if (calltype == 1) { var c = _Convert1by1(Pure.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(Pure.VM.OpCode.SYSCALL, null, to, outbytes); return(0); } else if (calltype == 4) { _Convert1by1(Pure.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(Pure.VM.OpCode.PACK, null, to); //a syscall { var bytes = Encoding.UTF8.GetBytes("Module.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(Pure.VM.OpCode.SYSCALL, null, to, outbytes); } } else if (calltype == 6) { _ConvertPush(callpcount, src, to); _Convert1by1(Pure.VM.OpCode.ROLL, null, to); byte[] nullhash = new byte[20]; //dyn appcall _Convert1by1(Pure.VM.OpCode.APPCALL, null, to, nullhash); } return(0); }