Пример #1
0
        /****
        *  Four cases:
        *  1. Ordinary method (not stubbed and not generic)
        *  2. Stubbed but not generic
        *  3. Not stubbed but generic
        *  4. Stubbed and generic
        *  Note that there are two sub-cases for "is stubbed": "stub present" or "stub absent".
        *  So that makes it a total of 6 cases.
        ****/
        public static IMethodDefinition CheckAndAdd(IMethodDefinition m)
        {
            IMethodDefinition lookFor = m;

            if (m is IGenericMethodInstance)
            {
                lookFor = GenericMethods.GetTemplate(m);
            }

            ITypeDefinition containingType = m.ContainingTypeDefinition;

            if (containingType.InternedKey == 0)
            {
                return(m);                                 // Ignore methods from Cci's Dummy typeref.
            }
            bool matches = MatchesSuppressM(m);

            if (matches)
            {
                containingType = Stubs.GetStubType(containingType);
                if (containingType == null)
                {
                    return(null);                        // This entire containingType is to be ignored.
                }
                lookFor = Utils.GetMethodSignMatch(containingType, lookFor);
                if (lookFor == null)
                {
                    return(null);                 // containingType itself is stubbed, but the stub does not define a method equivalent to m.
                }
            }

            IMethodDefinition methToAdd;

            if (m is IGenericMethodInstance)
            {
                // Here, lookFor is a template method
                methToAdd = GenericMethods.RecordInfo(lookFor, m, matches);
            }
            else
            {
                methToAdd = lookFor;
            }
            if (!rtaAnalyzer.visitedMethods.Contains(methToAdd) && !rtaAnalyzer.methods.Contains(methToAdd))
            {
                rtaAnalyzer.rtaLogSW.WriteLine("SRK_DBG: Adding method: {0}", methToAdd.FullName());
                rtaAnalyzer.methods.Add(methToAdd);
            }
            return(methToAdd);
        }
Пример #2
0
        public void ProcessVirtualInvoke(IMethodDefinition mCallee, ITypeDefinition calleeClass, bool isAddrTaken)
        {
            // mCallee is an ordinary method - never a template method.
            // calleeClass and mCallee are either both stubbed or, both unstubbed - i.e. they are consistent.
            bool isInterface = calleeClass.IsInterface;

            IMethodDefinition calleeTemplate = null;

            if (mCallee is IGenericMethodInstance)
            {
                calleeTemplate = (mCallee as IGenericMethodInstance).GenericMethod.ResolvedMethod;
            }

            foreach (ITypeDefinition cl in allocClasses)
            {
                if (cl is IArrayTypeReference)
                {
                    continue;
                }
                if (!Stubber.SuppressM(cl))
                {
                    bool process = false;
                    if (isInterface && Utils.ImplementsInterface(cl, calleeClass))
                    {
                        process = true;
                    }
                    if (Utils.ExtendsClass(cl, calleeClass))
                    {
                        process = true;
                    }
                    if (!process)
                    {
                        continue;
                    }
                    IMethodDefinition calleeArg;
                    if (mCallee is IGenericMethodInstance)
                    {
                        calleeArg = calleeTemplate;
                    }
                    else
                    {
                        calleeArg = mCallee;
                    }
                    IMethodDefinition meth = Utils.GetMethodSignMatchRecursive(cl, calleeArg);
                    if (meth == null)
                    {
                        continue;
                    }
                    if (meth.IsGeneric && calleeTemplate != null)
                    {
                        IMethodDefinition instMeth  = GenericMethods.RecordInfo(meth, mCallee, /* createIfReqd = */ true);
                        IMethodDefinition addedMeth = Stubber.CheckAndAdd(instMeth);
                        if (addedMeth != null && isAddrTaken)
                        {
                            addrTakenMethods.Add(addedMeth);
                        }
                    }
                    else if (meth.IsGeneric && calleeTemplate == null)
                    {
                        continue;
                    }
                    else if (!meth.IsGeneric && calleeTemplate != null)
                    {
                        continue;
                    }
                    else // meth is not generic and calleeTemplate is null
                    {
                        IMethodDefinition addedMeth = Stubber.CheckAndAdd(meth);
                        if (addedMeth != null && isAddrTaken)
                        {
                            addrTakenMethods.Add(addedMeth);
                        }
                    }
                }
            }
        }