public static void Parse(ILMethod from, BhpModule to) { calcStack = new Stack <object>(); bool bEnd = false; foreach (var src in from.body_Codes.Values) { if (bEnd) { break; } switch (src.code) { case CodeEx.Ret: bEnd = true; break; case CodeEx.Ldc_I4_M1: calcStack.Push((int)-1); break; case CodeEx.Ldc_I4_0: calcStack.Push((int)0); break; case CodeEx.Ldc_I4_1: calcStack.Push((int)1); break; case CodeEx.Ldc_I4_2: calcStack.Push((int)2); break; case CodeEx.Ldc_I4_3: calcStack.Push((int)3); break; case CodeEx.Ldc_I4_4: calcStack.Push((int)4); break; case CodeEx.Ldc_I4_5: calcStack.Push((int)5); break; case CodeEx.Ldc_I4_6: calcStack.Push((int)6); break; case CodeEx.Ldc_I4_7: calcStack.Push((int)7); break; case CodeEx.Ldc_I4_8: calcStack.Push((int)8); break; case CodeEx.Ldc_I4: case CodeEx.Ldc_I4_S: calcStack.Push((int)src.tokenI32); break; case CodeEx.Ldc_I8: calcStack.Push((long)src.tokenI64); break; case CodeEx.Newarr: { if ((src.tokenType == "System.Byte") || (src.tokenType == "System.SByte")) { var count = (int)calcStack.Pop(); byte[] data = new byte[count]; calcStack.Push(data); } else { throw new Exception("only byte[] can be defined in here."); } } break; case CodeEx.Dup: { var _src = calcStack.Peek(); var _dest = Dup(_src); calcStack.Push(_dest); } break; case CodeEx.Ldtoken: { calcStack.Push(src.tokenUnknown); } break; case CodeEx.Ldstr: { calcStack.Push(src.tokenStr); } break; case CodeEx.Call: { var m = src.tokenUnknown as Mono.Cecil.MethodReference; if (m.DeclaringType.FullName == "System.Runtime.CompilerServices.RuntimeHelpers" && m.Name == "InitializeArray") { var p1 = (byte[])calcStack.Pop(); var p2 = (byte[])calcStack.Pop(); for (var i = 0; i < p2.Length; i++) { p2[i] = p1[i]; } } else if (m.DeclaringType.FullName == "System.Numerics.BigInteger" && m.Name == "op_Implicit") { var type = m.Parameters[0].ParameterType.FullName; if (type == "System.UInt64") { var p = (ulong)(long)calcStack.Pop(); calcStack.Push(new System.Numerics.BigInteger(p).ToByteArray()); } else if (type == "System.UInt32") { var p = (ulong)(int)calcStack.Pop(); calcStack.Push(new System.Numerics.BigInteger(p).ToByteArray()); } else if (type == "System.Int64") { var p = (long)calcStack.Pop(); calcStack.Push(new System.Numerics.BigInteger(p).ToByteArray()); } else { var p = (int)calcStack.Pop(); calcStack.Push(new System.Numerics.BigInteger(p).ToByteArray()); } } else { foreach (var attr in m.Resolve().CustomAttributes) { if (attr.AttributeType.FullName == "Bhp.SmartContract.Framework.NonemitWithConvertAttribute") { var text = (string)calcStack.Pop(); var value = (int)attr.ConstructorArguments[0].Value; var type = attr.ConstructorArguments[0].Type.Resolve(); string attrname = ""; foreach (var f in type.Fields) { if (f.Constant != null && (int)f.Constant == value) { attrname = f.Name; break; } } if (attrname == "ToScriptHash") //AddressString2ScriptHashBytes to bytes { var bytes = Bhp.AllianceOfThinWallet.Cryptography.Base58.Decode(text); var hash = bytes.Skip(1).Take(20).ToArray(); calcStack.Push(hash); } else if (attrname == "HexToBytes") //HexString2Bytes to bytes[] { if (text.IndexOf("0x") == 0) { text = text.Substring(2); } var hex = HexString2Bytes(text); calcStack.Push(hex); } else if (attrname == "ToBigInteger") { var n = System.Numerics.BigInteger.Parse(text); calcStack.Push(n); } } } } } break; case CodeEx.Stsfld: { var field = src.tokenUnknown as Mono.Cecil.FieldReference; var fname = field.DeclaringType.FullName + "::" + field.Name; to.staticfields[fname] = calcStack.Pop(); } break; case CodeEx.Stelem_I1: { var v = (byte)(int)calcStack.Pop(); var index = (int)calcStack.Pop(); var array = calcStack.Pop() as byte[]; array[index] = v; } break; } } }
public static MyJson.JsonNode_Object Export(BhpModule module, byte[] script) { var sha256 = System.Security.Cryptography.SHA256.Create(); byte[] hash256 = sha256.ComputeHash(script); var ripemd160 = new Bhp.Cryptography.RIPEMD160Managed(); var hash = ripemd160.ComputeHash(hash256); var outjson = new MyJson.JsonNode_Object(); //hash StringBuilder sb = new StringBuilder(); sb.Append("0x"); foreach (var b in hash.Reverse().ToArray()) { sb.Append(b.ToString("x02")); } outjson.SetDictValue("hash", sb.ToString()); //entrypoint outjson.SetDictValue("entrypoint", "Main"); var mainmethod = module.mapMethods[module.mainMethod]; if (mainmethod != null) { var name = mainmethod.displayName; outjson.SetDictValue("entrypoint", name); } //functions var funcsigns = new MyJson.JsonNode_Array(); outjson["functions"] = funcsigns; List <string> names = new List <string>(); foreach (var function in module.mapMethods) { var mm = function.Value; if (mm.inSmartContract == false) { continue; } if (mm.isPublic == false) { continue; } var ps = mm.name.Split(new char[] { ' ', '(' }, StringSplitOptions.RemoveEmptyEntries); var funcsign = new MyJson.JsonNode_Object(); funcsigns.Add(funcsign); var funcname = ps[1]; if (funcname.IndexOf("::") > 0) { var sps = funcname.Split(new string[] { "::" }, StringSplitOptions.RemoveEmptyEntries); funcname = sps.Last(); } funcsign.SetDictValue("name", function.Value.displayName); if (names.Contains(function.Value.displayName)) { throw new Exception("abi not allow same name functions"); } names.Add(function.Value.displayName); MyJson.JsonNode_Array funcparams = new MyJson.JsonNode_Array(); funcsign["parameters"] = funcparams; if (mm.paramtypes != null) { foreach (var v in mm.paramtypes) { var ptype = ConvType(v.type); var item = new MyJson.JsonNode_Object(); funcparams.Add(item); item.SetDictValue("name", v.name); item.SetDictValue("type", ptype); } } var rtype = ConvType(mm.returntype); funcsign.SetDictValue("returntype", rtype); } //events var eventsigns = new MyJson.JsonNode_Array(); outjson["events"] = eventsigns; foreach (var events in module.mapEvents) { var mm = events.Value; var ps = mm.name.Split(new char[] { ' ', '(' }, StringSplitOptions.RemoveEmptyEntries); var funcsign = new MyJson.JsonNode_Object(); eventsigns.Add(funcsign); funcsign.SetDictValue("name", events.Value.displayName); MyJson.JsonNode_Array funcparams = new MyJson.JsonNode_Array(); funcsign["parameters"] = funcparams; if (mm.paramtypes != null) { foreach (var v in mm.paramtypes) { var ptype = ConvType(v.type); var item = new MyJson.JsonNode_Object(); funcparams.Add(item); item.SetDictValue("name", v.name); item.SetDictValue("type", ptype); } } var rtype = ConvType(mm.returntype); funcsign.SetDictValue("returntype", rtype); } return(outjson); }
private bool TryInsertMethod(BhpModule outModule, Mono.Cecil.MethodDefinition method) { var oldaddr = this.addr; var oldaddrconv = new Dictionary <int, int>(); foreach (int k in addrconv.Keys) { oldaddrconv[k] = addrconv[k]; } var typename = method.DeclaringType.FullName; ILType type; if (inModule.mapType.TryGetValue(typename, out type) == false) { type = new ILType(null, method.DeclaringType); inModule.mapType[typename] = type; } var _method = type.methods[method.FullName]; try { BhpMethod nm = new BhpMethod(); if (method.FullName.Contains(".cctor")) { CctorSubVM.Parse(_method, this.outModule); //continue; return(false); } if (method.IsConstructor) { return(false); //continue; } nm._namespace = method.DeclaringType.FullName; nm.name = method.FullName; nm.displayName = method.Name; Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = method.CustomAttributes; foreach (var attr in ca) { if (attr.AttributeType.Name == "DisplayNameAttribute") { nm.displayName = (string)attr.ConstructorArguments[0].Value; } } nm.inSmartContract = method.DeclaringType.BaseType.Name == "SmartContract"; nm.isPublic = method.IsPublic; this.methodLink[_method] = nm; outModule.mapMethods[nm.name] = nm; ConvertMethod(_method, nm); return(true); } catch { return(false); } finally { this.addr = oldaddr; this.addrconv.Clear(); foreach (int k in oldaddrconv.Keys) { addrconv[k] = oldaddrconv[k]; } } }
public BhpModule Convert(ILModule _in) { //logger.Log("beginConvert."); this.outModule = new BhpModule(this.logger); foreach (var t in _in.mapType) { if (t.Key.Contains("<")) { continue;//系统的,不要 } if (t.Key.Contains("_API_")) { continue; //api的,不要 } if (t.Key.Contains(".My.")) { continue;//vb system } foreach (var m in t.Value.methods) { if (m.Value.method == null) { continue; } if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn) { continue;//event 自动生成的代码,不要 } BhpMethod nm = new BhpMethod(); if (m.Key.Contains(".cctor")) { CctorSubVM.Parse(m.Value, this.outModule); continue; } if (m.Value.method.IsConstructor) { continue; } nm._namespace = m.Value.method.DeclaringType.FullName; nm.name = m.Value.method.FullName; nm.displayName = m.Value.method.Name; Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = m.Value.method.CustomAttributes; foreach (var attr in ca) { if (attr.AttributeType.Name == "DisplayNameAttribute") { nm.displayName = (string)attr.ConstructorArguments[0].Value; } } nm.inSmartContract = m.Value.method.DeclaringType.BaseType.Name == "SmartContract"; nm.isPublic = m.Value.method.IsPublic; this.methodLink[m.Value] = nm; outModule.mapMethods[nm.name] = nm; } foreach (var e in t.Value.fields) { if (e.Value.isEvent) { BhpEvent ae = new BhpEvent(); ae._namespace = e.Value.field.DeclaringType.FullName; ae.name = ae._namespace + "::" + e.Key; ae.displayName = e.Value.displayName; ae.returntype = e.Value.returntype; ae.paramtypes = e.Value.paramtypes; outModule.mapEvents[ae.name] = ae; } } } foreach (var t in _in.mapType) { if (t.Key.Contains("<")) { continue;//系统的,不要 } if (t.Key.Contains("_API_")) { continue; //api的,不要 } if (t.Key.Contains(".My.")) { continue;//vb system } foreach (var m in t.Value.methods) { if (m.Value.method == null) { continue; } if (m.Key.Contains(".cctor")) { continue; } if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn) { continue;//event 自动生成的代码,不要 } var nm = this.methodLink[m.Value]; //try { nm.returntype = m.Value.returntype; try { var type = m.Value.method.ReturnType.Resolve(); foreach (var i in type.Interfaces) { if (i.Name == "IApiInterface") { nm.returntype = "IInteropInterface"; } } } catch (Exception err) { } foreach (var src in m.Value.paramtypes) { nm.paramtypes.Add(new BhpParam(src.name, src.type)); } byte[] outcall; string name; if (IsAppCall(m.Value.method, out outcall)) { continue; } if (IsNonCall(m.Value.method)) { continue; } if (IsOpCall(m.Value.method, out name)) { continue; } if (IsSysCall(m.Value.method, out name)) { continue; } this.ConvertMethod(m.Value, nm); } //catch (Exception err) //{ // logger.Log("error:" + err.Message); //} } } //转换完了,做个link,全部拼到一起 string mainmethod = ""; foreach (var key in outModule.mapMethods.Keys) { if (key.Contains("::Main(")) { BhpMethod m = outModule.mapMethods[key]; if (m.inSmartContract) { foreach (var l in this.methodLink) { if (l.Value == m) { if (mainmethod != "") { throw new Exception("Have too mush EntryPoint,Check it."); } mainmethod = key; } } } } } if (mainmethod == "") { throw new Exception("Can't find EntryPoint,Check it."); } else { //单一默认入口 logger.Log("Find entrypoint:" + mainmethod); } outModule.mainMethod = mainmethod; this.LinkCode(mainmethod); //this.findFirstFunc();//得找到第一个函数 //然后给每个method 分配一个func addr //还需要对所有的call 做一次地址转换 //this.outModule.Build(); return(outModule); }
public BhpModule Convert(JavaModule _in) { this.srcModule = _in; //logger.Log("beginConvert."); this.outModule = new BhpModule(this.logger); foreach (var c in _in.classes.Values) { if (c.skip) { continue; } foreach (var m in c.methods) { if (m.Value.skip) { continue; } if (m.Key[0] == '<') { continue; //系統函數不要 } BhpMethod nm = new BhpMethod(); nm.name = c.classfile.Name + "::" + m.Key; nm.displayName = m.Key; nm.isPublic = m.Value.method.IsPublic; this.methodLink[m.Value] = nm; outModule.mapMethods[nm.name] = nm; } } foreach (var c in _in.classes.Values) { if (c.skip) { continue; } foreach (var m in c.methods) { if (m.Value.skip) { continue; } if (m.Key[0] == '<') { continue; //系統函數不要 } var nm = this.methodLink[m.Value]; //try { this.ConvertMethod(m.Value, nm); } //catch (Exception err) //{ // logger.Log("error:" + err.Message); //} } } //转换完了,做个link,全部拼到一起 string mainmethod = ""; foreach (var key in outModule.mapMethods.Keys) { var name = key.Substring(key.IndexOf("::") + 2); var i = name.IndexOf('('); name = name.Substring(0, i); if (name == ("Main")) { var m = outModule.mapMethods[key]; foreach (var l in this.methodLink) { if (l.Value == m) { var srcm = l.Key; if (srcm.DeclaringType.superClass == "org.bhp.smartcontract.framework.SmartContract") { logger.Log("Find entrypoint:" + key); if (mainmethod != "") { throw new Exception("Have too mush EntryPoint,Check it."); } mainmethod = key; } } } } } if (mainmethod == "") { throw new Exception("Can't find Main Method from SmartContract,Check it."); } outModule.mainMethod = mainmethod; //得找到第一个函数 this.LinkCode(mainmethod); //this.findFirstFunc();//得找到第一个函数 //然后给每个method 分配一个func addr //还需要对所有的call 做一次地址转换 //this.outModule.Build(); return(outModule); }