示例#1
0
        internal static void CrawlAppdomain(CSHotFix.Runtime.Enviorment.AppDomain domain, Dictionary <Type, CLRBindingGenerateInfo> infos)
        {
            var arr = domain.LoadedTypes.Values.ToArray();

            //Prewarm
            foreach (var type in arr)
            {
                if (type is CLR.TypeSystem.ILType)
                {
                    if (type.HasGenericParameter)
                    {
                        continue;
                    }
                    var methods = type.GetMethods().ToList();
                    foreach (var i in ((CLR.TypeSystem.ILType)type).GetConstructors())
                    {
                        methods.Add(i);
                    }
                    if (((CLR.TypeSystem.ILType)type).GetStaticConstroctor() != null)
                    {
                        methods.Add(((CLR.TypeSystem.ILType)type).GetStaticConstroctor());
                    }
                    foreach (var j in methods)
                    {
                        CLR.Method.ILMethod method = j as CLR.Method.ILMethod;
                        if (method != null)
                        {
                            if (method.GenericParameterCount > 0 && !method.IsGenericInstance)
                            {
                                continue;
                            }
                            var body = method.Body;
                        }
                    }
                }
            }
            arr = domain.LoadedTypes.Values.ToArray();
            foreach (var type in arr)
            {
                if (type is CLR.TypeSystem.ILType)
                {
                    if (type.TypeForCLR.IsByRef || type.HasGenericParameter)
                    {
                        continue;
                    }
                    var methods = type.GetMethods().ToList();
                    foreach (var i in ((CLR.TypeSystem.ILType)type).GetConstructors())
                    {
                        methods.Add(i);
                    }
                    if (((CLR.TypeSystem.ILType)type).GetStaticConstroctor() != null)
                    {
                        methods.Add(((CLR.TypeSystem.ILType)type).GetStaticConstroctor());
                    }
                    foreach (var j in methods)
                    {
                        CLR.Method.ILMethod method = j as CLR.Method.ILMethod;
                        if (method != null)
                        {
                            if (method.GenericParameterCount > 0 && !method.IsGenericInstance)
                            {
                                continue;
                            }
                            var body = method.Body;
                            foreach (var ins in body)
                            {
                                switch (ins.Code)
                                {
                                case Intepreter.OpCodes.OpCodeEnum.Newobj:
                                {
                                    CLR.Method.CLRMethod m = domain.GetMethod(ins.TokenInteger) as CLR.Method.CLRMethod;
                                    if (m != null)
                                    {
                                        if (m.DeclearingType.IsDelegate)
                                        {
                                            continue;
                                        }
                                        Type t = m.DeclearingType.TypeForCLR;
                                        CLRBindingGenerateInfo info;
                                        if (!infos.TryGetValue(t, out info))
                                        {
                                            info     = CreateNewBindingInfo(t);
                                            infos[t] = info;
                                        }
                                        if (m.IsConstructor)
                                        {
                                            info.Constructors.Add(m.ConstructorInfo);
                                        }
                                        else
                                        {
                                            info.Methods.Add(m.MethodInfo);
                                        }
                                    }
                                }
                                break;

                                case Intepreter.OpCodes.OpCodeEnum.Ldfld:
                                case Intepreter.OpCodes.OpCodeEnum.Stfld:
                                case Intepreter.OpCodes.OpCodeEnum.Ldflda:
                                case Intepreter.OpCodes.OpCodeEnum.Ldsfld:
                                case Intepreter.OpCodes.OpCodeEnum.Ldsflda:
                                case Intepreter.OpCodes.OpCodeEnum.Stsfld:
                                {
                                    var t = domain.GetType((int)(ins.TokenLong >> 32)) as CLR.TypeSystem.CLRType;
                                    if (t != null)
                                    {
                                        var fi = t.GetField((int)ins.TokenLong);
                                        if (fi != null && fi.IsPublic)
                                        {
                                            CLRBindingGenerateInfo info;
                                            if (!infos.TryGetValue(t.TypeForCLR, out info))
                                            {
                                                info = CreateNewBindingInfo(t.TypeForCLR);
                                                infos[t.TypeForCLR] = info;
                                            }
                                            if (ins.Code == Intepreter.OpCodes.OpCodeEnum.Stfld || ins.Code == Intepreter.OpCodes.OpCodeEnum.Stsfld)
                                            {
                                                if (t.IsValueType)
                                                {
                                                    info.ValueTypeNeeded       = true;
                                                    info.DefaultInstanceNeeded = true;
                                                }
                                            }
                                            if (t.TypeForCLR.CheckCanPinn() || !t.IsValueType)
                                            {
                                                info.Fields.Add(fi);
                                            }
                                        }
                                    }
                                }
                                break;

                                case Intepreter.OpCodes.OpCodeEnum.Ldtoken:
                                {
                                    if (ins.TokenInteger == 0)
                                    {
                                        var t = domain.GetType((int)(ins.TokenLong >> 32)) as CLR.TypeSystem.CLRType;
                                        if (t != null)
                                        {
                                            var fi = t.GetField((int)ins.TokenLong);
                                            if (fi != null)
                                            {
                                                CLRBindingGenerateInfo info;
                                                if (!infos.TryGetValue(t.TypeForCLR, out info))
                                                {
                                                    info = CreateNewBindingInfo(t.TypeForCLR);
                                                    infos[t.TypeForCLR] = info;
                                                }
                                                info.Fields.Add(fi);
                                            }
                                        }
                                    }
                                }
                                break;

                                case Intepreter.OpCodes.OpCodeEnum.Newarr:
                                {
                                    var t = domain.GetType(ins.TokenInteger) as CLR.TypeSystem.CLRType;
                                    if (t != null)
                                    {
                                        CLRBindingGenerateInfo info;
                                        if (!infos.TryGetValue(t.TypeForCLR, out info))
                                        {
                                            info = CreateNewBindingInfo(t.TypeForCLR);
                                            infos[t.TypeForCLR] = info;
                                        }
                                        info.ArrayNeeded = true;
                                    }
                                }
                                break;

                                case Intepreter.OpCodes.OpCodeEnum.Call:
                                case Intepreter.OpCodes.OpCodeEnum.Callvirt:
                                {
                                    CLR.Method.CLRMethod m = domain.GetMethod(ins.TokenInteger) as CLR.Method.CLRMethod;
                                    if (m != null)
                                    {
                                        //Cannot explicit call base class's constructor directly
                                        if (m.IsConstructor && m.DeclearingType.CanAssignTo(((CLR.TypeSystem.ILType)type).FirstCLRBaseType))
                                        {
                                            continue;
                                        }
                                        if (m.IsConstructor)
                                        {
                                            if (!m.ConstructorInfo.IsPublic)
                                            {
                                                continue;
                                            }
                                            Type t = m.DeclearingType.TypeForCLR;
                                            CLRBindingGenerateInfo info;
                                            if (!infos.TryGetValue(t, out info))
                                            {
                                                info     = CreateNewBindingInfo(t);
                                                infos[t] = info;
                                            }

                                            info.Constructors.Add(m.ConstructorInfo);
                                        }
                                        else
                                        {
                                            if (!m.MethodInfo.IsPublic)
                                            {
                                                continue;
                                            }
                                            Type t = m.DeclearingType.TypeForCLR;
                                            CLRBindingGenerateInfo info;
                                            if (!infos.TryGetValue(t, out info))
                                            {
                                                info     = CreateNewBindingInfo(t);
                                                infos[t] = info;
                                            }

                                            info.Methods.Add(m.MethodInfo);
                                        }
                                    }
                                }
                                break;
                                }
                            }
                        }
                    }
                }
            }
        }