示例#1
0
        /// <summary>
        /// Finds all the com objects in a given namespace and marks the methods of their subclasses as reachable.
        ///
        /// Perhaps too blunt.
        /// </summary>
        /// <param name="wholeProgram"></param>
        /// <param name="namespacePrefix"></param>
        /// <returns></returns>
        internal static ReachabilitySummary COMSummary(WholeProgram wholeProgram, String namespacePrefix)
        {
            // The ToString() here is probably not the best idea.
            IEnumerable <ITypeDefinition> comInterfaces = wholeProgram.AllDefinedTypes().Where(type => type.IsComObject &&
                                                                                               type.IsInterface &&
                                                                                               type.ToString().StartsWith("Microsoft.Cci"));

            ReachabilitySummary summary = new ReachabilitySummary();

            foreach (ITypeDefinition comInterface in comInterfaces)
            {
                summary.ReachableTypes.Add(comInterface);

                foreach (ITypeDefinition subtype in wholeProgram.ClassHierarchy().AllSubClassesOfClass(comInterface))
                {
                    summary.ConstructedTypes.Add(subtype);

                    foreach (IMethodDefinition method in subtype.Methods)
                    {
                        summary.NonvirtuallyCalledMethods.Add(method);
                    }
                }
            }

            return(summary);
        }
        public ReachabilitySummary SummarizeMethod(IMethodDefinition method, WholeProgram wholeProgram) {

            if (method.IsExternal == false && method.IsAbstract == false) {
                ReachabilitySummary summary = new ReachabilitySummary();
                IMethodDefinition target;


                // foreach MSIL instruction in the method
                foreach (var op in method.Body.Operations) {
                    switch (op.OperationCode) {
                        // non virtual method calls: just add static type
                        case OperationCode.Newobj:
                        case OperationCode.Call:
                        case OperationCode.Calli:
                            target = (op.Value as IMethodReference).ResolvedMethod;
                            summary.NonvirtuallyCalledMethods.Add(target);
                            break;

                        case OperationCode.Ldvirtftn:
                        case OperationCode.Callvirt:
                            target = (op.Value as IMethodReference).ResolvedMethod;            

                            if (target.IsVirtual == false) {
                                summary.NonvirtuallyCalledMethods.Add(target);
                            } else {
                                ITypeDefinition typeDefiningTarget = target.ContainingTypeDefinition;                                
                                IMethodDefinition targetUnspecialized = GarbageCollectHelper.UnspecializeAndResolveMethodReference(op.Value as IMethodReference);

                                // find all possible implementations of virtual call
                                foreach (ITypeDefinition subType in new ITypeDefinition[] { typeDefiningTarget }.Concat(wholeProgram.ClassHierarchy().AllSubClassesOfClass(typeDefiningTarget))) {
                                    if (GarbageCollectHelper.TypeIsConstructable(subType)) {

                                        // walk class hierarchy from subType up to (including) typeDefiningTarget, looking for targetUnspecialized.
                                        ICollection<IMethodDefinition> implementationsOfMethodDefinitionForSubType = GarbageCollectHelper.Implements(subType, typeDefiningTarget, targetUnspecialized);

                                        // we have to have found at least 1 implementation
                                        Contract.Assert(implementationsOfMethodDefinitionForSubType.Count() > 0);

                                        // add all of them as virtually called methods
                                        foreach (IMethodDefinition implementationOfTarget in implementationsOfMethodDefinitionForSubType) {
                                            summary.VirtuallyCalledMethods.Add(implementationOfTarget);
                                        }
                                    }
                                }

                            }
                            break;

                        default:
                            break;
                    }
                }

                return summary;
            } else {
                return null;
            }
        }
        private static ISet <ITypeDefinition> LookupTypesWithSpecifier(TypeSpecifier specifier, WholeProgram wholeProgram)
        {
            HashSet <ITypeDefinition> result = new HashSet <ITypeDefinition>(new TypeDefinitionEqualityComparer());

            string typeIdentifier = specifier.TypeIdentifier;


            switch (specifier.Kind)
            {
            case TypeSpecifierKind.Exactly:
                result.Add(LookupExactTypeWithIdentifier(typeIdentifier, wholeProgram));
                break;

            case TypeSpecifierKind.Subtypes:
                // t-devinc: We really out to change this to include the type itself, not just all of its proper subtypes
                result.UnionWith(wholeProgram.ClassHierarchy().AllSubClassesOfClass(LookupExactTypeWithIdentifier(typeIdentifier, wholeProgram)));
                break;

            case TypeSpecifierKind.Matches:
                return(LookupTypesMatchingRegexpIdentifier(typeIdentifier, wholeProgram));
            }

            return(result);
        }
        public ReachabilitySummary SummarizeMethod(IMethodDefinition method, WholeProgram wholeProgram)
        {
            if (method.IsExternal == false && method.IsAbstract == false)
            {
                ReachabilitySummary summary = new ReachabilitySummary();
                IMethodDefinition   target;


                // foreach MSIL instruction in the method
                foreach (var op in method.Body.Operations)
                {
                    switch (op.OperationCode)
                    {
                    // non virtual method calls: just add static type
                    case OperationCode.Newobj:
                    case OperationCode.Call:
                    case OperationCode.Calli:
                        target = (op.Value as IMethodReference).ResolvedMethod;
                        summary.NonvirtuallyCalledMethods.Add(target);
                        break;

                    case OperationCode.Ldvirtftn:
                    case OperationCode.Callvirt:
                        target = (op.Value as IMethodReference).ResolvedMethod;

                        if (target.IsVirtual == false)
                        {
                            summary.NonvirtuallyCalledMethods.Add(target);
                        }
                        else
                        {
                            ITypeDefinition   typeDefiningTarget  = target.ContainingTypeDefinition;
                            IMethodDefinition targetUnspecialized = GarbageCollectHelper.UnspecializeAndResolveMethodReference(op.Value as IMethodReference);

                            // find all possible implementations of virtual call
                            foreach (ITypeDefinition subType in new ITypeDefinition[] { typeDefiningTarget }.Concat(wholeProgram.ClassHierarchy().AllSubClassesOfClass(typeDefiningTarget)))
                            {
                                if (GarbageCollectHelper.TypeIsConstructable(subType))
                                {
                                    // walk class hierarchy from subType up to (including) typeDefiningTarget, looking for targetUnspecialized.
                                    ICollection <IMethodDefinition> implementationsOfMethodDefinitionForSubType = GarbageCollectHelper.Implements(subType, typeDefiningTarget, targetUnspecialized);

                                    // we have to have found at least 1 implementation
                                    Contract.Assert(implementationsOfMethodDefinitionForSubType.Count() > 0);

                                    // add all of them as virtually called methods
                                    foreach (IMethodDefinition implementationOfTarget in implementationsOfMethodDefinitionForSubType)
                                    {
                                        summary.VirtuallyCalledMethods.Add(implementationOfTarget);
                                    }
                                }
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }

                return(summary);
            }
            else
            {
                return(null);
            }
        }
示例#5
0
        private void NoteVirtualDispatch(IMethodDefinition methodDispatchedUpon)
        {
            Contract.Requires(methodDispatchedUpon != null);
            Contract.Requires(!(methodDispatchedUpon is Dummy));
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(methodDispatchedUpon));
            Contract.Requires(methodDispatchedUpon.IsVirtual);

            Contract.Ensures(VirtualMethodIsInDemand(methodDispatchedUpon));

            //Console.WriteLine("VirtCallFound on {0} of type {1}", methodDefinition, methodDefinition.GetType());

            bool virtualMethodIsAlreadyKnown = VirtualMethodIsInDemand(methodDispatchedUpon);

            MarkVirtualMethodAsInDemand(methodDispatchedUpon);

            if (virtualMethodIsAlreadyKnown)
            {
                return;
            }

            // The code below this point is called only the first time we learn that
            // someone has dispatched against this method.

            //Console.WriteLine("{0} has {1} derived methods", methodDefinition, this.callgraph.GetAllDerivedMethods(methodDefinition).ToArray().Length);


            ITypeDefinition typeDefiningM = methodDispatchedUpon.ContainingTypeDefinition;

            this.TypeUseFound(typeDefiningM);

            // t-devinc: clean this up
            foreach (ITypeDefinition subType in new ITypeDefinition[] { typeDefiningM }.Concat(wholeProgram.ClassHierarchy().AllSubClassesOfClass(typeDefiningM)))
            {
                if (GarbageCollectHelper.TypeIsConstructable(subType) && ((subType.IsStruct || constructed.Contains(subType))))
                {
                    ICollection <IMethodDefinition> implementationsOfMethodDefinitionForSubType = GarbageCollectHelper.Implements(subType, typeDefiningM, methodDispatchedUpon);

                    Contract.Assert(implementationsOfMethodDefinitionForSubType.Count() > 0);

                    foreach (IMethodDefinition implementationOfM in implementationsOfMethodDefinitionForSubType)
                    {
                        NoteDispatch(methodDispatchedUpon, GarbageCollectHelper.UnspecializeAndResolveMethodReference(implementationOfM), subType);
                    }
                }
            }
        }
    /// <summary>
    /// Finds all the com objects in a given namespace and marks the methods of their subclasses as reachable.
    /// 
    /// Perhaps too blunt.
    /// </summary>
    /// <param name="wholeProgram"></param>
    /// <param name="namespacePrefix"></param>
    /// <returns></returns>
    internal static ReachabilitySummary COMSummary(WholeProgram wholeProgram, String namespacePrefix) {

      // The ToString() here is probably not the best idea.
      IEnumerable<ITypeDefinition> comInterfaces = wholeProgram.AllDefinedTypes().Where(type => type.IsComObject &&
                                                                                          type.IsInterface &&
                                                                                          type.ToString().StartsWith("Microsoft.Cci"));

      ReachabilitySummary summary = new ReachabilitySummary();

      foreach (ITypeDefinition comInterface in comInterfaces) {
        summary.ReachableTypes.Add(comInterface);

        foreach (ITypeDefinition subtype in wholeProgram.ClassHierarchy().AllSubClassesOfClass(comInterface)) {
          summary.ConstructedTypes.Add(subtype);

          foreach (IMethodDefinition method in subtype.Methods) {
            summary.NonvirtuallyCalledMethods.Add(method);
          }
        }
      }

      return summary;
    }