| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984 | using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Reflection;using ILRuntime.Mono.Cecil;using ILRuntime.Runtime;using ILRuntime.Runtime.Intepreter.OpCodes;using ILRuntime.Runtime.Intepreter;using ILRuntime.Runtime.Intepreter.RegisterVM;using ILRuntime.Runtime.Debugger;using ILRuntime.CLR.TypeSystem;using ILRuntime.Reflection;namespace ILRuntime.CLR.Method{    public class ILMethod : IMethod    {        OpCode[] body;        OpCodeR[] bodyRegister;        Dictionary<int, RegisterVMSymbol> registerSymbols;        bool symbolFixed;        MethodDefinition def;        List<IType> parameters;        ILRuntime.Runtime.Enviorment.AppDomain appdomain;        ILType declaringType;        ExceptionHandler[] exceptionHandler, exceptionHandlerR;        KeyValuePair<string, IType>[] genericParameters;        IType[] genericArguments;        Dictionary<int, int[]> jumptables, jumptablesR;        bool isDelegateInvoke;        bool jitPending;        ILRuntimeMethodInfo refletionMethodInfo;        ILRuntimeConstructorInfo reflectionCtorInfo;        int paramCnt, localVarCnt, stackRegisterCnt;        int jitFlags;        bool jitOnDemand;        bool jitImmediately;        int warmupCounter = 0;        Mono.Collections.Generic.Collection<Mono.Cecil.Cil.VariableDefinition> variables;        int hashCode = -1;        static int instance_id = 0x10000000;        const int JITWarmUpThreshold = 10;        public bool Compiling { get; set; }        public bool IsRegisterBodyReady { get { return bodyRegister != null; } }        public MethodDefinition Definition { get { return def; } }        public Dictionary<int, int[]> JumpTables { get { return jumptables; } }        public Dictionary<int, int[]> JumpTablesRegister { get { return jumptablesR; } }        internal Dictionary<int, RegisterVMSymbol> RegisterVMSymbols { get { return registerSymbols; } }        internal int JITFlags { get { return jitFlags; } }        internal bool IsRegisterVMSymbolFixed { get { return symbolFixed; } }        internal IDelegateAdapter DelegateAdapter { get; set; }        internal int StartLine { get; set; }        internal int EndLine { get; set; }        public ILRuntime.Runtime.Enviorment.AppDomain AppDomain { get { return appdomain; } }        public MethodInfo ReflectionMethodInfo        {            get            {                if (IsConstructor)                    throw new NotSupportedException();                if (refletionMethodInfo == null)                    refletionMethodInfo = new ILRuntimeMethodInfo(this);                return refletionMethodInfo;            }        }        public ConstructorInfo ReflectionConstructorInfo        {            get            {                if (!IsConstructor)                    throw new NotSupportedException();                if (reflectionCtorInfo == null)                    reflectionCtorInfo = new ILRuntimeConstructorInfo(this);                return reflectionCtorInfo;            }        }        internal ExceptionHandler[] ExceptionHandler        {            get            {                return exceptionHandler;            }        }        internal ExceptionHandler[] ExceptionHandlerRegister        {            get            {                return exceptionHandlerR;            }        }        public string Name        {            get            {                return def.Name;            }        }        public IType DeclearingType        {            get            {                return declaringType;            }        }        public bool HasThis        {            get            {                return def.HasThis;            }        }        public int GenericParameterCount        {            get            {                if (IsGenericInstance)                    return 0;                return def.GenericParameters.Count;            }        }        public bool IsGenericInstance        {            get            {                return genericParameters != null;            }        }        public Mono.Collections.Generic.Collection<Mono.Cecil.Cil.VariableDefinition> Variables        {            get            {                return variables;            }        }        public KeyValuePair<string, IType>[] GenericArguments { get { return genericParameters; } }        public IType[] GenericArugmentsArray { get { return genericArguments; } }        public bool ShouldUseRegisterVM        {            get            {                if (bodyRegister != null)                {                    body = null;                    exceptionHandler = null;                    return true;                }                else                {                    if (jitImmediately)                    {                        InitCodeBody(true);                        return true;                    }                    else                    {                        if (jitOnDemand)                        {                            warmupCounter++;                            if (warmupCounter > JITWarmUpThreshold && !jitPending)                            {                                jitPending = true;                                AppDomain.EnqueueJITCompileJob(this);                            }                        }                        return false;                    }                }            }        }        public ILMethod(MethodDefinition def, ILType type, ILRuntime.Runtime.Enviorment.AppDomain domain, int flags)        {            this.def = def;            declaringType = type;            this.jitFlags = flags;            if (def.ReturnType.IsGenericParameter)            {                ReturnType = FindGenericArgument(def.ReturnType.Name);            }            else                ReturnType = domain.GetType(def.ReturnType, type, this);            if (type.IsDelegate && def.Name == "Invoke")                isDelegateInvoke = true;            this.appdomain = domain;            paramCnt = def.HasParameters ? def.Parameters.Count : 0;            if(def.HasCustomAttributes)            {                for(int i = 0; i < def.CustomAttributes.Count; i++)                {                    int f;                    if(def.CustomAttributes[i].GetJITFlags(domain, out f))                    {                        this.jitFlags = f;                        break;                    }                }            }            jitImmediately = (jitFlags & ILRuntimeJITFlags.JITImmediately) == ILRuntimeJITFlags.JITImmediately;            jitOnDemand = (jitFlags & ILRuntimeJITFlags.JITOnDemand) == ILRuntimeJITFlags.JITOnDemand;#if DEBUG && !DISABLE_ILRUNTIME_DEBUG            if (def.HasBody)            {                var sp = GetValidSequence(0, 1);                if (sp != null)                {                    StartLine = sp.StartLine;                    sp = GetValidSequence(def.Body.Instructions.Count - 1, -1);                    if (sp != null)                    {                        EndLine = sp.EndLine;                    }                }            }#endif        }        public void FixRegisterVMSymbol()        {            if (!symbolFixed && registerSymbols != null)            {                symbolFixed = true;                JITCompiler.FixSymbol(registerSymbols);            }        }        Mono.Cecil.Cil.SequencePoint GetValidSequence(int startIdx, int dir)        {            var seqMapping = def.DebugInformation.GetSequencePointMapping();            var cur = DebugService.FindSequencePoint(def.Body.Instructions[startIdx], seqMapping);            while (cur != null && cur.StartLine == 0x0feefee)            {                startIdx += dir;                if (startIdx >= 0 && startIdx < def.Body.Instructions.Count)                {                    cur = DebugService.FindSequencePoint(def.Body.Instructions[startIdx], seqMapping);                }                else                    break;            }            return cur;        }        public IType FindGenericArgument(string name)        {            IType res = declaringType.FindGenericArgument(name);            if (res == null && genericParameters != null)            {                foreach (var i in genericParameters)                {                    if (i.Key == name)                        return i.Value;                }            }            else                return res;            return null;        }        internal OpCode[] Body        {            get            {                if (body == null)                    InitCodeBody(false);                return body;            }        }        internal OpCodeR[] BodyRegister        {            get            {                if (bodyRegister == null)                    InitCodeBody(true);                return bodyRegister;            }        }        public bool HasBody        {            get            {                return body != null;            }        }        public int LocalVariableCount        {            get            {                return localVarCnt;            }        }        public int StackRegisterCount        {            get            {                return stackRegisterCnt;            }        }        public bool IsConstructor        {            get            {                return def.IsConstructor;            }        }        public bool IsVirtual        {            get            {                return def.IsVirtual;            }        }        public bool IsDelegateInvoke        {            get            {                return isDelegateInvoke;            }        }        public bool IsStatic        {            get { return def.IsStatic; }        }        public int ParameterCount        {            get            {                return paramCnt;            }        }        public List<IType> Parameters        {            get            {                if (def.HasParameters && parameters == null)                {                    InitParameters();                }                return parameters;            }        }        public IType ReturnType        {            get;            private set;        }        public void Prewarm(bool recursive)        {            HashSet<ILMethod> alreadyPrewarmed = null;            if (recursive)            {                alreadyPrewarmed = new HashSet<ILMethod>();            }            Prewarm(alreadyPrewarmed);        }        void PrewarmBody(HashSet<ILMethod> alreadyPrewarmed)        {            //当前方法用到的IType,提前InitializeMethods()。各个子调用,提前InitParameters()            var body = Body;            foreach (var ins in body)            {                switch (ins.Code)                {                    case OpCodeEnum.Call:                    case OpCodeEnum.Newobj:                    case OpCodeEnum.Ldftn:                    case OpCodeEnum.Ldvirtftn:                    case OpCodeEnum.Callvirt:                        {                            var m = appdomain.GetMethod(ins.TokenInteger);                            if (m is ILMethod)                            {                                ILMethod ilm = (ILMethod)m;                                //如果参数alreadyPrewarmed不为空,则不仅prewarm当前方法,还会递归prewarm所有子调用                                //如果参数alreadyPrewarmed为空,则只prewarm当前方法                                if (alreadyPrewarmed != null)                                {                                    ilm.Prewarm(alreadyPrewarmed);                                }                            }                            else if (m is CLRMethod)                            {                                CLRMethod clrm = (CLRMethod)m;                                ILRuntime.CLR.Utils.Extensions.GetTypeFlags(clrm.DeclearingType.TypeForCLR);                            }                        }                        break;                    case OpCodeEnum.Ldfld:                    case OpCodeEnum.Stfld:                    case OpCodeEnum.Ldflda:                    case OpCodeEnum.Ldsfld:                    case OpCodeEnum.Ldsflda:                    case OpCodeEnum.Stsfld:                    case OpCodeEnum.Ldtoken:                        {                            //提前InitializeBaseType()                            var t = appdomain.GetType((int)(ins.TokenLong >> 32));                            if (t != null)                            {                                var baseType = t.BaseType;                            }                        }                        break;                }            }        }        void PrewarmBodyRegister(HashSet<ILMethod> alreadyPrewarmed)        {            //当前方法用到的IType,提前InitializeMethods()。各个子调用,提前InitParameters()            var body = BodyRegister;            foreach (var ins in body)            {                switch (ins.Code)                {                    case OpCodeREnum.Call:                    case OpCodeREnum.Newobj:                    case OpCodeREnum.Ldftn:                    case OpCodeREnum.Ldvirtftn:                    case OpCodeREnum.Callvirt:                        {                            var m = appdomain.GetMethod(ins.Operand);                            if (m is ILMethod)                            {                                ILMethod ilm = (ILMethod)m;                                //如果参数alreadyPrewarmed不为空,则不仅prewarm当前方法,还会递归prewarm所有子调用                                //如果参数alreadyPrewarmed为空,则只prewarm当前方法                                if (alreadyPrewarmed != null)                                {                                    ilm.Prewarm(alreadyPrewarmed);                                }                            }                            else if (m is CLRMethod)                            {                                CLRMethod clrm = (CLRMethod)m;                                ILRuntime.CLR.Utils.Extensions.GetTypeFlags(clrm.DeclearingType.TypeForCLR);                            }                        }                        break;                    case OpCodeREnum.Ldfld:                    case OpCodeREnum.Stfld:                    case OpCodeREnum.Ldflda:                    case OpCodeREnum.Ldsfld:                    case OpCodeREnum.Ldsflda:                    case OpCodeREnum.Stsfld:                    case OpCodeREnum.Ldtoken:                        {                            //提前InitializeBaseType()                            var t = appdomain.GetType((int)(ins.OperandLong >> 32));                            if (t != null)                            {                                var baseType = t.BaseType;                            }                        }                        break;                }            }        }        private void Prewarm(HashSet<ILMethod> alreadyPrewarmed)        {            if (alreadyPrewarmed != null && alreadyPrewarmed.Add(this) == false)                return;            if (GenericParameterCount > 0 && !IsGenericInstance)                return;            //当前方法用到的CLR局部变量,提前InitializeFields()、GetTypeFlags()            for (int i = 0; i < LocalVariableCount; i++)            {                var v = Variables[i];                var vt = v.VariableType;                IType t;                if (vt.IsGenericParameter)                {                    t = FindGenericArgument(vt.Name);                }                else                {                    t = appdomain.GetType(v.VariableType, DeclearingType, this);                }                if (t is CLRType)                {                    CLRType ct = (CLRType)t;                    var fields = ct.Fields;                    ILRuntime.CLR.Utils.Extensions.GetTypeFlags(ct.TypeForCLR);                }            }            if (jitImmediately || jitOnDemand)                PrewarmBodyRegister(alreadyPrewarmed);            else                PrewarmBody(alreadyPrewarmed);        }        internal void InitCodeBody(bool register)        {            if (def.HasBody)            {                localVarCnt = def.Body.Variables.Count;                Dictionary<Mono.Cecil.Cil.Instruction, int> addr = new Dictionary<Mono.Cecil.Cil.Instruction, int>();                bool noRelease = false;                if (register)                {                    JITCompiler jit = new JITCompiler(appdomain, declaringType, this);                    bodyRegister = jit.Compile(out stackRegisterCnt, out jumptablesR, addr, out registerSymbols);                }                else                {                    InitStackCodeBody(addr);                    if (jitOnDemand)                        noRelease = bodyRegister == null;                }                if (def.Body.ExceptionHandlers.Count > 0)                {                    ExceptionHandler[] ehs;                    if (register)                    {                        if (exceptionHandlerR == null)                            exceptionHandlerR = new Method.ExceptionHandler[def.Body.ExceptionHandlers.Count];                        ehs = exceptionHandlerR;                    }                    else                    {                        if (exceptionHandler == null)                            exceptionHandler = new Method.ExceptionHandler[def.Body.ExceptionHandlers.Count];                        ehs = exceptionHandler;                    }                    for (int i = 0; i < def.Body.ExceptionHandlers.Count; i++)                    {                        var eh = def.Body.ExceptionHandlers[i];                        ExceptionHandler e = new ExceptionHandler();                        e.HandlerStart = addr[eh.HandlerStart];                        e.HandlerEnd = eh.HandlerEnd != null ? addr[eh.HandlerEnd] - 1 : def.Body.Instructions.Count - 1;                        e.TryStart = addr[eh.TryStart];                        e.TryEnd = addr[eh.TryEnd] - 1;                        switch (eh.HandlerType)                        {                            case Mono.Cecil.Cil.ExceptionHandlerType.Catch:                                e.CatchType = appdomain.GetType(eh.CatchType, declaringType, this);                                e.HandlerType = ExceptionHandlerType.Catch;                                break;                            case Mono.Cecil.Cil.ExceptionHandlerType.Finally:                                e.HandlerType = ExceptionHandlerType.Finally;                                break;                            case Mono.Cecil.Cil.ExceptionHandlerType.Fault:                                e.HandlerType = ExceptionHandlerType.Fault;                                break;                            default:                                throw new NotImplementedException();                        }                        ehs[i] = e;                    }                    //Mono.Cecil.Cil.ExceptionHandlerType.                }                variables = def.Body.Variables;#if !DEBUG || DISABLE_ILRUNTIME_DEBUG                //Release Method body to save memory                if(!noRelease)                    def.Body = null;#endif            }            else                body = new OpCode[0];        }        void InitStackCodeBody(Dictionary<Mono.Cecil.Cil.Instruction, int> addr)        {            body = new OpCode[def.Body.Instructions.Count];            for (int i = 0; i < body.Length; i++)            {                var c = def.Body.Instructions[i];                OpCode code = new OpCode();                code.Code = (OpCodeEnum)c.OpCode.Code;                addr[c] = i;                body[i] = code;            }            for (int i = 0; i < body.Length; i++)            {                var c = def.Body.Instructions[i];                InitToken(ref body[i], c.Operand, addr);                if (i > 0 && c.OpCode.Code == Mono.Cecil.Cil.Code.Callvirt && def.Body.Instructions[i - 1].OpCode.Code == Mono.Cecil.Cil.Code.Constrained)                {                    body[i - 1].TokenLong = body[i].TokenInteger;                }            }        }        unsafe void InitToken(ref OpCode code, object token, Dictionary<Mono.Cecil.Cil.Instruction, int> addr)        {            switch (code.Code)            {                case OpCodeEnum.Leave:                case OpCodeEnum.Leave_S:                case OpCodeEnum.Br:                case OpCodeEnum.Br_S:                case OpCodeEnum.Brtrue:                case OpCodeEnum.Brtrue_S:                case OpCodeEnum.Brfalse:                case OpCodeEnum.Brfalse_S:                //比较流程控制                case OpCodeEnum.Beq:                case OpCodeEnum.Beq_S:                case OpCodeEnum.Bne_Un:                case OpCodeEnum.Bne_Un_S:                case OpCodeEnum.Bge:                case OpCodeEnum.Bge_S:                case OpCodeEnum.Bge_Un:                case OpCodeEnum.Bge_Un_S:                case OpCodeEnum.Bgt:                case OpCodeEnum.Bgt_S:                case OpCodeEnum.Bgt_Un:                case OpCodeEnum.Bgt_Un_S:                case OpCodeEnum.Ble:                case OpCodeEnum.Ble_S:                case OpCodeEnum.Ble_Un:                case OpCodeEnum.Ble_Un_S:                case OpCodeEnum.Blt:                case OpCodeEnum.Blt_S:                case OpCodeEnum.Blt_Un:                case OpCodeEnum.Blt_Un_S:                    code.TokenInteger = addr[(Mono.Cecil.Cil.Instruction)token];                    break;                case OpCodeEnum.Ldc_I4:                    code.TokenInteger = (int)token;                    break;                case OpCodeEnum.Ldc_I4_S:                    code.TokenInteger = (sbyte)token;                    break;                case OpCodeEnum.Ldc_I8:                    code.TokenLong = (long)token;                    break;                case OpCodeEnum.Ldc_R4:                    {                        float val = (float)token;                        code.TokenInteger = *(int*)&val;                    }                    break;                case OpCodeEnum.Ldc_R8:                    {                        double val = (double)token;                        code.TokenLong = *(long*)&val;                    }                    break;                case OpCodeEnum.Stloc:                case OpCodeEnum.Stloc_S:                case OpCodeEnum.Ldloc:                case OpCodeEnum.Ldloc_S:                case OpCodeEnum.Ldloca:                case OpCodeEnum.Ldloca_S:                    {                        Mono.Cecil.Cil.VariableDefinition vd = (Mono.Cecil.Cil.VariableDefinition)token;                        code.TokenInteger = vd.Index;                    }                    break;                case OpCodeEnum.Ldarg_S:                case OpCodeEnum.Ldarg:                case OpCodeEnum.Ldarga:                case OpCodeEnum.Ldarga_S:                case OpCodeEnum.Starg:                case OpCodeEnum.Starg_S:                    {                        Mono.Cecil.ParameterDefinition vd = (Mono.Cecil.ParameterDefinition)token;                        code.TokenInteger = vd.Index;                        if (HasThis)                            code.TokenInteger++;                    }                    break;                case OpCodeEnum.Call:                case OpCodeEnum.Newobj:                case OpCodeEnum.Ldftn:                case OpCodeEnum.Ldvirtftn:                case OpCodeEnum.Callvirt:                    {                        bool invalidToken;                        var m = appdomain.GetMethod(token, declaringType, this, out invalidToken);                        if (m != null)                        {                            if(code.Code == OpCodeEnum.Callvirt && m is ILMethod)                            {                                ILMethod ilm = (ILMethod)m;                                if (!ilm.def.IsAbstract && !ilm.def.IsVirtual && !ilm.DeclearingType.IsInterface)                                    code.Code = OpCodeEnum.Call;                            }                            if (invalidToken)                                code.TokenInteger = m.GetHashCode();                            else                                code.TokenInteger = token.GetHashCode();                        }                        else                        {                            //Cannot find method or the method is dummy                            MethodReference _ref = (MethodReference)token;                            int paramCnt = _ref.HasParameters ? _ref.Parameters.Count : 0;                            if (_ref.HasThis)                                paramCnt++;                            code.TokenLong = paramCnt;                        }                    }                    break;                case OpCodeEnum.Constrained:                case OpCodeEnum.Box:                case OpCodeEnum.Unbox_Any:                case OpCodeEnum.Unbox:                case OpCodeEnum.Initobj:                case OpCodeEnum.Isinst:                case OpCodeEnum.Newarr:                case OpCodeEnum.Stobj:                case OpCodeEnum.Ldobj:                    {                        code.TokenInteger = GetTypeTokenHashCode(token);                    }                    break;                case OpCodeEnum.Stfld:                case OpCodeEnum.Ldfld:                case OpCodeEnum.Ldflda:                    {                        code.TokenLong = appdomain.GetStaticFieldIndex(token, declaringType, this);                    }                    break;                case OpCodeEnum.Stsfld:                case OpCodeEnum.Ldsfld:                case OpCodeEnum.Ldsflda:                    {                        code.TokenLong = appdomain.GetStaticFieldIndex(token, declaringType, this);                    }                    break;                case OpCodeEnum.Ldstr:                    {                        long hashCode = appdomain.CacheString(token);                        code.TokenLong = hashCode;                    }                    break;                case OpCodeEnum.Ldtoken:                    {                        if (token is FieldReference)                        {                            code.TokenInteger = 0;                            code.TokenLong = appdomain.GetStaticFieldIndex(token, declaringType, this);                        }                        else if (token is TypeReference)                        {                            code.TokenInteger = 1;                            code.TokenLong = GetTypeTokenHashCode(token);                        }                        else                            throw new NotImplementedException();                    }                    break;                case OpCodeEnum.Switch:                    {                        PrepareJumpTable(token, addr);                        code.TokenInteger = token.GetHashCode();                    }                    break;            }        }        internal int GetTypeTokenHashCode(object token)        {            var t = appdomain.GetType(token, declaringType, this);            bool isGenericParameter = CheckHasGenericParamter(token);            if (t == null && isGenericParameter)            {                t = FindGenericArgument(((TypeReference)token).Name);            }            if (t != null)            {                if (t is ILType || isGenericParameter)                {                    return t.GetHashCode();                }                else                    return token.GetHashCode();            }            return 0;        }        bool CheckHasGenericParamter(object token)        {            if (token is TypeReference)            {                TypeReference _ref = ((TypeReference)token);                if (_ref.IsArray)                    return CheckHasGenericParamter(((ArrayType)_ref).ElementType);                if (_ref.IsGenericParameter)                    return true;                if (_ref.IsGenericInstance)                {                    GenericInstanceType gi = (GenericInstanceType)_ref;                    foreach(var i in gi.GenericArguments)                    {                        if (CheckHasGenericParamter(i))                            return true;                    }                    return false;                }                else                    return false;            }            else                return false;        }        void PrepareJumpTable(object token, Dictionary<Mono.Cecil.Cil.Instruction, int> addr)        {            int hashCode = token.GetHashCode();            if (jumptables == null)                jumptables = new Dictionary<int, int[]>();            if (jumptables.ContainsKey(hashCode))                return;            Mono.Cecil.Cil.Instruction[] e = token as Mono.Cecil.Cil.Instruction[];            int[] addrs = new int[e.Length];            for (int i = 0; i < e.Length; i++)            {                addrs[i] = addr[e[i]];            }            jumptables[hashCode] = addrs;        }        void InitParameters()        {            parameters = new List<IType>();            foreach (var i in def.Parameters)            {                IType type = null;                bool isByRef = false;                bool isArray = false;                int rank = 1;                TypeReference pt = i.ParameterType;                if (pt.IsByReference)                {                    isByRef = true;                    pt = ((ByReferenceType)pt).ElementType;                }                if (pt.IsArray)                {                    isArray = true;                    rank = ((ArrayType)pt).Rank;                    pt = ((ArrayType)pt).ElementType;                }                if (pt.IsGenericParameter)                {                    type = FindGenericArgument(pt.Name);                    if (type == null && def.HasGenericParameters)                    {                        bool found = false;                        foreach (var j in def.GenericParameters)                        {                            if (j.Name == pt.Name)                            {                                found = true;                                break;                            }                        }                        if (found)                        {                            type = new ILGenericParameterType(pt.Name);                        }                        else                            throw new NotSupportedException("Cannot find Generic Parameter " + pt.Name + " in " + def.FullName);                    }                }                else                    type = appdomain.GetType(pt, declaringType, this);                if (isArray)                    type = type.MakeArrayType(rank);                if (isByRef)                    type = type.MakeByRefType();                parameters.Add(type);            }        }        public IMethod MakeGenericMethod(IType[] genericArguments)        {            KeyValuePair<string, IType>[] genericParameters = new KeyValuePair<string, IType>[genericArguments.Length];            for (int i = 0; i < genericArguments.Length; i++)            {                string name = def.GenericParameters[i].Name;                IType val = genericArguments[i];                genericParameters[i] = new KeyValuePair<string, IType>(name, val);            }            ILMethod m = new ILMethod(def, declaringType, appdomain, jitFlags);            m.genericParameters = genericParameters;            m.genericArguments = genericArguments;            if (m.def.ReturnType.IsGenericParameter)            {                m.ReturnType = m.FindGenericArgument(m.def.ReturnType.Name);            }            return m;        }        string cachedName;        public override string ToString()        {            if (cachedName == null)            {                StringBuilder sb = new StringBuilder();                sb.Append(declaringType.FullName);                sb.Append('.');                sb.Append(Name);                sb.Append('(');                bool isFirst = true;                if (parameters == null)                    InitParameters();                for (int i = 0; i < parameters.Count; i++)                {                    if (isFirst)                        isFirst = false;                    else                        sb.Append(", ");                    sb.Append(parameters[i].FullName);                    sb.Append(' ');                    sb.Append(def.Parameters[i].Name);                }                sb.Append(')');                cachedName = sb.ToString();            }            return cachedName;        }        public override int GetHashCode()        {            if (hashCode == -1)                hashCode = System.Threading.Interlocked.Add(ref instance_id, 1);            return hashCode;        }        bool? isExtend;        public bool IsExtend        {            get            {                if (isExtend == null)                {                    isExtend = this.IsExtendMethod();                }                return isExtend.Value;            }        }    }}
 |