Example #1
0
        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;
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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;
                }
            }
        }
Example #4
0
        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))
Example #5
0
        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);
        }
Example #6
0
        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;
                }
            }
        }
Example #9
0
        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);
        }
Example #10
0
        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))
Example #11
0
        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))
Example #15
0
        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;
                }
            }
        }
Example #16
0
        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);
        }
Example #17
0
        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);
        }