private bool TryInsertMethod(NeoModule outModule, Mono.Cecil.MethodDefinition method) { var oldaddr = this.addr; 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 { NeoMethod nm = new NeoMethod(); 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; } }
public static MyJson.JsonNode_Object Export(NeoModule module, byte[] script) { var sha256 = System.Security.Cryptography.SHA256.Create(); byte[] hash256 = sha256.ComputeHash(script); var ripemd160 = new Neo.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; foreach (var function in module.mapMethods) { var mm = function.Value; 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); 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); }
public static void Parse(ILMethod from, NeoModule 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 == "Neo.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 = NEO.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.FullName; // 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 NeoModule Convert(ILModule _in, ConvOption option = null) { this.inModule = _in; //logger.Log("beginConvert."); this.outModule = new NeoModule(this.logger) { option = option ?? ConvOption.Default }; 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 自动生成的代码,不要 } if (m.Value.method.Is_cctor()) { CctorSubVM.Parse(m.Value, this.outModule); continue; } if (m.Value.method.Is_ctor()) { continue; } NeoMethod nm = new NeoMethod(m.Value); this.methodLink[m.Value] = nm; outModule.mapMethods[nm.name] = nm; } foreach (var e in t.Value.fields) { if (e.Value.isEvent) { NeoEvent ae = new NeoEvent(e.Value); outModule.mapEvents[ae.name] = ae; } else if (e.Value.field.IsStatic) { var _fieldindex = outModule.mapFields.Count; var field = new NeoField(e.Key, e.Value.type, _fieldindex); outModule.mapFields[e.Value.field.FullName] = field; } } } var keys = new List <string>(_in.mapType.Keys); foreach (var key in keys) { var value = _in.mapType[key]; if (key.Contains("<")) { continue;//系统的,不要 } if (key.Contains("_API_")) { continue; //api的,不要 } if (key.Contains(".My.")) { continue;//vb system } foreach (var m in value.methods) { if (m.Value.method == null) { continue; } if (m.Value.method.Is_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.InterfaceType.Name == "IApiInterface") { nm.returntype = "IInteropInterface"; } } } catch { } foreach (var src in m.Value.paramtypes) { nm.paramtypes.Add(new NeoParam(src.name, src.type)); } if (IsAppCall(m.Value.method, out byte[] outcall))
public NeoModule Convert(ILModule _in) { //logger.Log("beginConvert."); this.outModule = new NeoModule(this.logger); foreach (var t in _in.mapType) { if (t.Key[0] == '<') { 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 自动生成的代码,不要 } NeoMethod nm = new NeoMethod(); if (m.Key == ".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.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) { NeoEvent ae = new NeoEvent(); 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; } } } Dictionary <byte, string> spmains = new Dictionary <byte, string>(); foreach (var t in _in.mapType) { if (t.Key[0] == '<') { 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 == ".cctor") { continue; } if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn) { continue;//event 自动生成的代码,不要 } var nm = this.methodLink[m.Value]; byte entryid; if (IsEntryCall(m.Value.method, out entryid)) { spmains[entryid] = nm.name; logger.Log("Find entrypoint:[" + entryid + "]" + nm.name); } //try { nm.returntype = m.Value.returntype; foreach (var src in m.Value.paramtypes) { nm.paramtypes.Add(new NeoParam(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(")) { NeoMethod m = outModule.mapMethods[key]; foreach (var l in this.methodLink) { if (l.Value == m) { var srcm = l.Key.method; if (srcm.DeclaringType.BaseType.Name == "SmartContract") { if (mainmethod != "") { throw new Exception("Have too mush EntryPoint,Check it."); } mainmethod = key; } } } } } if (mainmethod == "" && spmains.Count == 0) { throw new Exception("Can't find EntryPoint,Check it."); } else if (mainmethod != "" && spmains.Count > 0) { throw new Exception("Have Main Method and Spec EntryPoint sametime,Check it."); } else if (mainmethod != "") { //单一默认入口 logger.Log("Find entrypoint:" + mainmethod); } else if (spmains.Count > 0) //拥有条件入口的情况 { mainmethod = this.CreateJmpMain(spmains); } outModule.mainMethod = mainmethod; this.LinkCode(mainmethod); //this.findFirstFunc();//得找到第一个函数 //然后给每个method 分配一个func addr //还需要对所有的call 做一次地址转换 //this.outModule.Build(); return(outModule); }
public static MyJson.JsonNode_Object Export(NeoModule module, byte[] script, Dictionary <int, int> addrConvTable) { var sha256 = System.Security.Cryptography.SHA256.Create(); byte[] hash256 = sha256.ComputeHash(script); var ripemd160 = new Neo.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()); //functions var methods = new MyJson.JsonNode_Array(); outjson["methods"] = methods; 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 funcsign = new MyJson.JsonNode_Object(); methods.Add(funcsign); 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); var offset = addrConvTable?[function.Value.funcaddr] ?? function.Value.funcaddr; funcsign.SetDictValue("offset", offset.ToString()); 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 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); } } //event do not have returntype in nep3 //var rtype = ConvType(mm.returntype); //funcsign.SetDictValue("returntype", rtype); } return(outjson); }
public NeoModule Convert(JavaModule _in) { this.srcModule = _in; //logger.Log("beginConvert."); this.outModule = new NeoModule(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; //系統函數不要 } NeoMethod nm = new NeoMethod(); 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); 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.neo.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); }
public static void Parse(ILMethod from, NeoModule 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.Newarr: { if (src.tokenType == "System.Byte") { var count = (int)calcStack.Pop(); byte[] data = new byte[count]; calcStack.Push(data); } } 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 { foreach (var attr in m.Resolve().CustomAttributes) { if (attr.AttributeType.FullName == "Neo.SmartContract.Framework.NonemitWithConvertAttribute") { var text = (string)calcStack.Pop(); var value = (int)attr.ConstructorArguments[0].Value; if (value == 1) //AddressString2ScriptHashBytes to bytes { var bytes = NEO.AllianceOfThinWallet.Cryptography.Base58.Decode(text); var hash = bytes.Skip(1).Take(20).ToArray(); calcStack.Push(hash); } else if (value == 0) //HexString2Bytes to bytes[] { if (text.IndexOf("0x") == 0) { text = text.Substring(2); } var hex = HexString2Bytes(text); calcStack.Push(hex); } } } } } 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; } } }
public static MyJson.JsonNode_Object ExportDebugInfo(string avmName, NeoModule module) { var outjson = new MyJson.JsonNode_Object(); var debugMap = new List <DebugMapEntry>(); DebugMapEntry currentDebugEntry = null; var fileMap = new Dictionary <string, int>(); List <byte> bytes = new List <byte>(); foreach (var c in module.total_Codes.Values) { if (c.debugcode != null && c.debugline > 0 && c.debugline < 2000) { var previousDebugEntry = currentDebugEntry; currentDebugEntry = new DebugMapEntry(); if (previousDebugEntry != null) { currentDebugEntry.startOfs = previousDebugEntry.endOfs + 1; currentDebugEntry.endOfs = bytes.Count; } else { currentDebugEntry.startOfs = 0; currentDebugEntry.endOfs = bytes.Count; } currentDebugEntry.url = c.debugcode; currentDebugEntry.line = c.debugline; if (!fileMap.ContainsKey(c.debugcode)) { fileMap[c.debugcode] = fileMap.Count + 1; } debugMap.Add(currentDebugEntry); } else if (currentDebugEntry != null) { currentDebugEntry.endOfs = bytes.Count; } bytes.Add((byte)c.code); if (c.bytes != null) { for (var i = 0; i < c.bytes.Length; i++) { bytes.Add(c.bytes[i]); } } } string compilerName = System.AppDomain.CurrentDomain.FriendlyName.ToLowerInvariant(); var version = Assembly.GetEntryAssembly().GetName().Version.ToString(); var avmInfo = new MyJson.JsonNode_Object(); avmInfo.Add("name", new MyJson.JsonNode_ValueString(avmName)); //avmInfo.Add("hash", new MyJson.JsonNode_ValueString(hash)); var compilerInfo = new MyJson.JsonNode_Object(); compilerInfo.Add("name", new MyJson.JsonNode_ValueString(compilerName)); compilerInfo.Add("version", new MyJson.JsonNode_ValueString(version)); var fileInfo = new MyJson.JsonNode_Array(); foreach (var entry in fileMap) { var fileEntry = new MyJson.JsonNode_Object(); fileEntry.Add("id", new MyJson.JsonNode_ValueNumber(entry.Value)); fileEntry.Add("url", new MyJson.JsonNode_ValueString(entry.Key)); fileInfo.AddArrayValue(fileEntry); } var mapInfo = new MyJson.JsonNode_Array(); foreach (var entry in debugMap) { if (!fileMap.ContainsKey(entry.url)) { continue; } var fileID = fileMap[entry.url]; var mapEntry = new MyJson.JsonNode_Object(); mapEntry.Add("start", new MyJson.JsonNode_ValueNumber(entry.startOfs)); mapEntry.Add("end", new MyJson.JsonNode_ValueNumber(entry.endOfs)); mapEntry.Add("file", new MyJson.JsonNode_ValueNumber(fileID)); mapEntry.Add("line", new MyJson.JsonNode_ValueNumber(entry.line)); mapInfo.AddArrayValue(mapEntry); } outjson["avm"] = avmInfo; outjson["compiler"] = compilerInfo; outjson["files"] = fileInfo; outjson["map"] = mapInfo; return(outjson); }
public NeoModule Convert(ILModule _in, ConvOption option = null) { this.inModule = _in; //logger.Log("beginConvert."); this.outModule = new NeoModule(this.logger) { option = option ?? ConvOption.Default }; 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 自动生成的代码,不要 } NeoMethod nm = new NeoMethod(); 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) { NeoEvent ae = new NeoEvent { _namespace = e.Value.field.DeclaringType.FullName, name = e.Value.field.DeclaringType.FullName + "::" + e.Key, displayName = e.Value.displayName, returntype = e.Value.returntype, paramtypes = e.Value.paramtypes }; outModule.mapEvents[ae.name] = ae; } else if (e.Value.field.IsStatic) { var _fieldindex = outModule.mapFields.Count; var field = new NeoField(e.Key, e.Value.type, _fieldindex); outModule.mapFields[e.Value.field.FullName] = field; } } } var keys = new List <string>(_in.mapType.Keys); foreach (var key in keys) { var value = _in.mapType[key]; if (key.Contains("<")) { continue;//系统的,不要 } if (key.Contains("_API_")) { continue; //api的,不要 } if (key.Contains(".My.")) { continue;//vb system } foreach (var m in 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.InterfaceType.Name == "IApiInterface") { nm.returntype = "IInteropInterface"; } } } catch { } foreach (var src in m.Value.paramtypes) { nm.paramtypes.Add(new NeoParam(src.name, src.type)); } if (IsAppCall(m.Value.method, out byte[] outcall))
public NeoModule Convert(ILModule _in) { //logger.Log("beginConvert."); this.outModule = new NeoModule(this.logger); foreach (var t in _in.mapType) { if (t.Key.Contains("<")) { continue;//系统的,不要 system, no } if (t.Key.Contains("_API_")) { continue; //api的,不要 api, do not } 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 自动生成的代码,不要 Auto - generated code, do not } NeoMethod nm = new NeoMethod(); 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) { NeoEvent ae = new NeoEvent(); 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;//系统的,不要 Systematic, no } if (t.Key.Contains("_API_")) { continue; //api的,不要 api, do not } 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 自动生成的代码,不要 Auto-generated code, do not } 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) { } foreach (var src in m.Value.paramtypes) { nm.paramtypes.Add(new NeoParam(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,全部拼到一起 Conversion finished, be a link, all together string mainmethod = ""; foreach (var key in outModule.mapMethods.Keys) { if (key.Contains("::Main(")) { NeoMethod 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 { //单一默认入口 Single default entry logger.Log("Find entrypoint:" + mainmethod); } outModule.mainMethod = mainmethod; this.LinkCode(mainmethod); //this.findFirstFunc();//得找到第一个函数 Have to find the first function //然后给每个method 分配一个func addr Then assign a func addr to each method //还需要对所有的call 做一次地址转换 Also need to do an address translation for all calls //this.outModule.Build(); return(outModule); }
public static bool Parse(ILMethod from, NeoModule to) { bool constValue = true; bool ret = false; calcStack = new Stack <object>(); Dictionary <int, object> location = new System.Collections.Generic.Dictionary <int, object>(); bool bEnd = false; foreach (var src in from.body_Codes.Values) { if (bEnd || ret) { break; } switch (src.code) { case CodeEx.Add: //add two numbers is easy,but this will make code more complex. //need to find a safe way to process all kind of calc. throw new Exception("not support opcode [Add] in cctor."); case CodeEx.Nop: continue; case CodeEx.Stloc: location[src.tokenI32] = calcStack.Pop(); break; case CodeEx.Stloc_0: location[0] = calcStack.Pop(); break; case CodeEx.Stloc_1: location[1] = calcStack.Pop(); break; case CodeEx.Stloc_2: location[2] = calcStack.Pop(); break; case CodeEx.Stloc_3: location[3] = calcStack.Pop(); break; case CodeEx.Ldloc: calcStack.Push(location[src.tokenI32]); break; case CodeEx.Ldloc_0: calcStack.Push(location[0]); break; case CodeEx.Ldloc_1: calcStack.Push(location[1]); break; case CodeEx.Ldloc_2: calcStack.Push(location[2]); break; case CodeEx.Ldloc_3: calcStack.Push(location[3]); break; case CodeEx.Conv_I1: case CodeEx.Conv_I2: case CodeEx.Conv_I4: case CodeEx.Conv_I8: case CodeEx.Conv_U1: case CodeEx.Conv_U2: case CodeEx.Conv_U4: case CodeEx.Conv_U8: continue; 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(); if (count > MaxArraySize) { throw new ArgumentException("MaxArraySize found"); } byte[] data = new byte[count]; calcStack.Push(data); } else if (src.tokenType == "System.String") { var count = (int)calcStack.Pop(); if (count > MaxArraySize) { throw new ArgumentException("MaxArraySize found"); } string[] data = new string[count]; calcStack.Push(data); } else { //other type mean is not a constValue constValue = false; continue; } } 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") { if (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 if (m.Name == "Parse") { switch (calcStack.Count) { case 1: { var p = calcStack.Pop(); if (p is string pstr) { p = System.Numerics.BigInteger.Parse(pstr); calcStack.Push(p); break; } throw new InvalidOperationException("Unsupported call to BigInteger.Parse"); } case 2: { var s = calcStack.Pop(); var p = calcStack.Pop(); if (p is string pstr) { if (s is int) { p = System.Numerics.BigInteger.Parse(pstr, (NumberStyles)s); calcStack.Push(p); break; } else if (s is IFormatProvider) { p = System.Numerics.BigInteger.Parse(pstr, (IFormatProvider)s); calcStack.Push(p); break; } } throw new InvalidOperationException("Unsupported call to BigInteger.Parse"); } default: throw new InvalidOperationException("Unsupported call to BigInteger.Parse"); } } } else { foreach (var attr in m.Resolve().CustomAttributes) { if (attr.AttributeType.FullName == "Neo.SmartContract.Framework.NonemitWithConvertAttribute") { 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 text = (string)calcStack.Pop(); var bytes = Base58.Decode(text); var hash = bytes.Skip(1).Take(20).ToArray(); calcStack.Push(hash); } else if (attrname == "HexToBytes") //HexString2Bytes to bytes[] { var reverse = (int)calcStack.Pop() != 0; var text = (string)calcStack.Pop(); var hex = text.HexString2Bytes(); if (reverse) { hex = hex.Reverse().ToArray(); } calcStack.Push(hex); } } if (attr.AttributeType.FullName == "Neo.SmartContract.Framework.SyscallAttribute") { // If there is a syscall in cctor, we should add it into staticfieldsCctor directly. // Then the initializemethod will handle it. ret = true; constValue = false; break; } } } } break; case CodeEx.Stsfld: { var field = src.tokenUnknown as Mono.Cecil.FieldReference; var fname = field.FullName; if (calcStack.Count == 0) { constValue = false; to.staticfieldsWithConstValue[fname] = null; } else { to.staticfieldsWithConstValue[fname] = calcStack.Pop(); } // field.DeclaringType.FullName + "::" + field.Name; } break; case CodeEx.Stelem_Ref: { var refValue = calcStack.Pop(); if (refValue is string) // Currently, we only support string ref { var strValue = (string)refValue; var index = (int)calcStack.Pop(); var array = calcStack.Pop() as string[]; if (array is null) { constValue = false; break; } array[index] = strValue; } 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; default: throw new Exception("not support opcode " + src + " in cctor."); } } if (constValue == false) { if (to.staticfieldsCctor.Contains(from) == false) { to.staticfieldsCctor.Add(from); } } return(constValue); }
public NeoModule Convert(ILModule _in, ConvOption option = null) { this.inModule = _in; this.outModule = new NeoModule() { option = option ?? ConvOption.Default }; foreach (var t in _in.mapType) { if (t.Key.Contains("<")) { continue; //skip system type } if (t.Key.Contains("_API_")) { continue; // skip 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; // skip the code generated by event } if (m.Value.method.Is_ctor()) { continue; } if (m.Value.method.Is_cctor()) { //if cctor contains sth can not be as a const value. // then need 1.record these cctor's code. // 2.insert them to main function CctorSubVM.Parse(m.Value, this.outModule); continue; } NeoMethod nm = new NeoMethod(m.Value); this.methodLink[m.Value] = nm; outModule.mapMethods[nm.name] = nm; } foreach (var e in t.Value.fields) { if (e.Value.isEvent) { NeoEvent ae = new NeoEvent(e.Value); outModule.mapEvents[ae.name] = ae; } else if (e.Value.field.IsStatic) { var _fieldindex = outModule.mapFields.Count; var field = new NeoField(e.Key, e.Value.type, _fieldindex); outModule.mapFields[e.Value.field.FullName] = field; } } } var keys = new List <string>(_in.mapType.Keys); foreach (var key in keys) { var value = _in.mapType[key]; if (key.Contains("<")) { continue; // skip system typee } if (key.Contains("_API_")) { continue; // skip api } if (key.Contains(".My.")) { continue; //vb system } foreach (var m in value.methods) { if (m.Value.method == null) { continue; } if (m.Value.method.Is_cctor()) { continue; } if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn) { continue; // skip the code generated by event } var nm = this.methodLink[m.Value]; //try { nm.returntype = m.Value.returntype; foreach (var src in m.Value.paramtypes) { nm.paramtypes.Add(new NeoParam(src.name, src.type)); } if (IsContractCall(m.Value.method, out _)) { continue; } if (IsNonCall(m.Value.method)) { continue; } if (IsMixAttribute(m.Value.method, out _, out _)) { continue; } if (m.Key.Contains("::Main(")) { NeoMethod _m = outModule.mapMethods[m.Key]; } this.ConvertMethod(m.Value, nm); } } } if (this.outModule.mapFields.Count > MAX_STATIC_FIELDS_COUNT) { throw new Exception("too much static fields"); } if (this.outModule.mapFields.Count > 0) { InsertInitializeMethod(); logger.Log("Insert _initialize()."); } var attr = outModule.mapMethods.Values.Where(u => u.inSmartContract).Select(u => u.type?.attributes.ToArray()).FirstOrDefault(); if (attr?.Length > 0) { outModule.attributes.AddRange(attr); } var declaringTypes = outModule.mapMethods.Values .Where(u => u.inSmartContract) .Select(u => u.method?.method?.DeclaringType) .Where(u => u != null && !string.IsNullOrEmpty(u.Name)) .Distinct() .ToArray(); outModule.Name = declaringTypes.Length == 1 ? declaringTypes[0].Name : Path.GetFileNameWithoutExtension(_in.module.Name); this.LinkCode(); // this.findFirstFunc();// Need to find the first method // Assign func addr for each method // Then convert the call address return(outModule); }
public NeoModule Convert(ILModule _in, ConvOption option = null) { this.inModule = _in; this.outModule = new NeoModule(this.logger) { option = option ?? ConvOption.Default }; foreach (var t in _in.mapType) { if (t.Key.Contains("<")) { continue; //skip system type } if (t.Key.Contains("_API_")) { continue; // skip 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; // skip the code generated by event } if (m.Value.method.Is_ctor()) { continue; } if (m.Value.method.Is_cctor()) { //if cctor contains sth can not be as a const value. // then need 1.record these cctor's code. // 2.insert them to main function CctorSubVM.Parse(m.Value, this.outModule); continue; } NeoMethod nm = new NeoMethod(m.Value); this.methodLink[m.Value] = nm; outModule.mapMethods[nm.name] = nm; } foreach (var e in t.Value.fields) { if (e.Value.isEvent) { NeoEvent ae = new NeoEvent(e.Value); outModule.mapEvents[ae.name] = ae; } else if (e.Value.field.IsStatic) { var _fieldindex = outModule.mapFields.Count; var field = new NeoField(e.Key, e.Value.type, _fieldindex); outModule.mapFields[e.Value.field.FullName] = field; } } } var keys = new List <string>(_in.mapType.Keys); foreach (var key in keys) { var value = _in.mapType[key]; if (key.Contains("<")) { continue; // skip system typee } if (key.Contains("_API_")) { continue; // skip api } if (key.Contains(".My.")) { continue; //vb system } foreach (var m in value.methods) { if (m.Value.method == null) { continue; } if (m.Value.method.Is_cctor()) { continue; } if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn) { continue; // skip the code generated by event } var nm = this.methodLink[m.Value]; //try { nm.returntype = m.Value.returntype; foreach (var src in m.Value.paramtypes) { nm.paramtypes.Add(new NeoParam(src.name, src.type)); } if (IsContractCall(m.Value.method, out byte[] outcall))
public static void Parse(ILMethod from, NeoModule 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.Newarr: { if (src.tokenType == "System.Byte") { var count = (int)calcStack.Pop(); byte[] data = new byte[count]; calcStack.Push(data); } } 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.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]; } } } 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; } } }
public NeoModule Convert(ILModule _in, ConvOption option = null) { this.inModule = _in; //logger.Log("beginConvert."); this.outModule = new NeoModule(this.logger); this.outModule.option = option == null ? ConvOption.Default : option; 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 自动生成的代码,不要 } NeoMethod nm = new NeoMethod(); 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) { NeoEvent ae = new NeoEvent(); 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; } } } var keys = new List <string>(_in.mapType.Keys); foreach (var key in keys) { var value = _in.mapType[key]; if (key.Contains("<")) { continue;//系统的,不要 } if (key.Contains("_API_")) { continue; //api的,不要 } if (key.Contains(".My.")) { continue;//vb system } foreach (var m in 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.InterfaceType.Name == "IApiInterface") { nm.returntype = "IInteropInterface"; } } } catch (Exception err) { } foreach (var src in m.Value.paramtypes) { nm.paramtypes.Add(new NeoParam(src.name, src.type)); } byte[] outcall; string name; VM.OpCode[] opcodes; string[] opdata; if (IsAppCall(m.Value.method, out outcall)) { continue; } if (IsNonCall(m.Value.method)) { continue; } if (IsMixAttribute(m.Value.method, out opcodes, out opdata)) { 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(")) { NeoMethod 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 bool compile(string filename, string filetext, out byte[] avmtext, out string abitext, out string maptext, out string hash) { var tree = CSharpSyntaxTree.ParseText(filetext); var comp = CSharpCompilation.Create("aaa.dll", new[] { tree }, new[] { ref1, ref2, ref3, ref4 }, op); var fs = new MemoryStream(); var fspdb = new MemoryStream(); var result = comp.Emit(fs, fspdb); fs.Seek(0, SeekOrigin.Begin); fspdb.Seek(0, SeekOrigin.Begin); ILModule mod = new ILModule(); mod.LoadModule(fs, fspdb); NeoModule am = null; byte[] bytes = null; string jsonstr = null; string mapInfo = null; ConvOption option = new ConvOption() { useNep8 = false }; var conv = new ModuleConverter(new DefLogger()); am = conv.Convert(mod, option); // *.avm bytes = am.Build(); avmtext = bytes; // *.abi.json var outjson = vmtool.FuncExport.Export(am, bytes); jsonstr = outjson.ToString(); abitext = jsonstr; hash = outjson["hash"].ToString(); // *.map.json Neo.Compiler.MyJson.JsonNode_Array arr = new Neo.Compiler.MyJson.JsonNode_Array(); foreach (var m in am.mapMethods) { Neo.Compiler.MyJson.JsonNode_Object item = new Neo.Compiler.MyJson.JsonNode_Object(); arr.Add(item); item.SetDictValue("name", m.Value.displayName); item.SetDictValue("addr", m.Value.funcaddr.ToString("X04")); Neo.Compiler.MyJson.JsonNode_Array infos = new Neo.Compiler.MyJson.JsonNode_Array(); item.SetDictValue("map", infos); foreach (var c in m.Value.body_Codes) { if (c.Value.debugcode != null) { var debugcode = c.Value.debugcode.ToLower(); //if (debugcode.Contains(".cs")) { infos.AddArrayValue(c.Value.addr.ToString("X04") + "-" + c.Value.debugline.ToString()); } } } } mapInfo = arr.ToString(); maptext = mapInfo; try { fs.Dispose(); if (fspdb != null) { fspdb.Dispose(); } } catch { } return(true); }