internal MapGenericMethodParameters(IMetadataHost host, IGenericMethodInstance genericMethodInstance)
            : base(host, copyAndRewriteImmutableReferences: true)
        {
            Contract.Requires(host != null);
            Contract.Requires(genericMethodInstance != null);

            this.genericArguments = IteratorHelper.GetAsArray(genericMethodInstance.GenericArguments);
        }
        public bool TestAssemGenericMethodCall()
        {
            ITypeDefinition   type      = Helper.GetNamespaceType((IUnitNamespace)this.ModuleReaderTest.AssemblyAssembly.NamespaceRoot, this.Assem);
            IMethodDefinition method    = Helper.GetMethodNamed(type, this.GenMethod);
            IOperation        op        = Helper.GetOperation(method, 7);
            IMethodReference  methodRef = op.Value as IMethodReference;

            if (methodRef == null)
            {
                return(false);
            }
            IGenericMethodInstance gmi = methodRef.ResolvedMethod as IGenericMethodInstance;

            if (gmi == null)
            {
                return(false);
            }
            StringILDasmPaper   stringPaper   = new StringILDasmPaper(2);
            ILDasmPrettyPrinter prettyPrinter = new ILDasmPrettyPrinter(stringPaper, this.ModuleReaderTest.TestAssembly);

            prettyPrinter.MethodDefinition(gmi);
            string result =
                @".method public hidebysig instance explicit default[mscorlib]System.Object GenMethod<[mscorlib]System.Object>(
  [mscorlib]System.Object  t,
  [mscorlib]System.Collections.Generic.List`1<[mscorlib]System.Object> l,
  [mscorlib]System.Object[] ta,
  [mscorlib]System.Object[,] tm,
  [mscorlib]System.Object[,] tn
)cil managed
{
  .maxstack 6
  .locals init(
     V_0
  )
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldnull
  IL_0003:  ldnull
  IL_0004:  ldnull
  IL_0005:  ldnull
  IL_0006:  ldnull
  IL_0007:  call instance!!0[MRW_Assembly]Assem::GenMethod<[mscorlib]System.Object>(!!0,[mscorlib]System.Collections.Generic.List`1<!!0>,!!0[],!!0[,],!!0[,])
  IL_000c:  pop
  IL_000d:  ldarg.1
  IL_000e:  stloc.0
  IL_000f:  br.s IL_0011
  IL_0011:  ldloc.0
  IL_0012:  ret
}
";

            return(result.Equals(stringPaper.Content));
        }
Example #3
0
        /// <summary>
        /// A specialized method definition or generic method instance does not have a body. Given a method definition,
        /// find the unspecialized version of the definition and fetch the body.
        /// </summary>
        /// <param name="methodDefinition"></param>
        /// <returns></returns>
        internal static IMethodBody GetMethodBodyFromUnspecializedVersion(IMethodDefinition methodDefinition)
        {
            IGenericMethodInstance genericMethodInstance = methodDefinition as IGenericMethodInstance;

            if (genericMethodInstance != null)
            {
                return(GetMethodBodyFromUnspecializedVersion(genericMethodInstance.GenericMethod.ResolvedMethod));
            }
            ISpecializedMethodDefinition specializedMethodDefinition = methodDefinition as ISpecializedMethodDefinition;

            if (specializedMethodDefinition != null)
            {
                return(GetMethodBodyFromUnspecializedVersion(specializedMethodDefinition.UnspecializedVersion.ResolvedMethod));
            }
            return(methodDefinition.Body);
        }
Example #4
0
        /// <summary>
        /// Get the unspecialized method definition is <paramref name="methodDefinition"/> is a specialized
        /// version, or itself otherwise.
        /// </summary>
        /// <param name="methodDefinition"></param>
        /// <returns></returns>
        internal static IMethodDefinition UnspecializedMethodDefinition(IMethodDefinition methodDefinition)
        {
            IGenericMethodInstance genericMethodInstance = methodDefinition as IGenericMethodInstance;

            if (genericMethodInstance != null)
            {
                methodDefinition = genericMethodInstance.GenericMethod.ResolvedMethod;
            }
            ISpecializedMethodDefinition specializedMethodDefinition = methodDefinition as ISpecializedMethodDefinition;

            if (specializedMethodDefinition != null)
            {
                return(specializedMethodDefinition.UnspecializedVersion);
            }
            return(methodDefinition);
        }
Example #5
0
        /// <summary>
        /// See if a method definition is compiler generated, or is inside a compiler generated type.
        /// </summary>
        /// <param name="methodDefinition"></param>
        /// <returns></returns>
        internal static bool IsCompilerGenerated(IMethodDefinition /*!*/ methodDefinition)
        {
            if (AttributeHelper.Contains(methodDefinition.Attributes, methodDefinition.ContainingType.PlatformType.SystemRuntimeCompilerServicesCompilerGeneratedAttribute))
            {
                return(true);
            }
            IGenericMethodInstance genericMethodInstance = methodDefinition as IGenericMethodInstance;

            if (genericMethodInstance != null)
            {
                return(IsCompilerGenerated(genericMethodInstance.GenericMethod.ResolvedMethod));
            }
            if (methodDefinition.ContainingType == null)
            {
                return(false);
            }
            return(IsCompilerGenerated(methodDefinition.ContainingType));
        }
Example #6
0
        public static IMethodDefinition GetInstantiatedMeth(IMethodDefinition templateMeth, IMethodDefinition instMeth)
        {
            IGenericMethodInstance       genericM       = instMeth as IGenericMethodInstance;
            IEnumerable <ITypeReference> genericArgs    = genericM.GenericArguments;
            IList <ITypeReference>       stubbedArgList = new List <ITypeReference>();

            foreach (ITypeReference garg in genericArgs)
            {
                ITypeDefinition addedType = Stubber.CheckAndAdd(garg.ResolvedType);
                if (addedType != null)
                {
                    stubbedArgList.Add(addedType);
                }
                else
                {
                    stubbedArgList.Add(garg.ResolvedType);
                }
            }
            string argStr = GetGenericArgStr(stubbedArgList);
            IDictionary <string, IMethodDefinition> instMap;

            if (ClassAndMethodVisitor.genericMethodMap.ContainsKey(templateMeth))
            {
                instMap = ClassAndMethodVisitor.genericMethodMap[templateMeth];
            }
            else
            {
                instMap = new Dictionary <string, IMethodDefinition>();
                ClassAndMethodVisitor.genericMethodMap[templateMeth] = instMap;
            }
            if (instMap.ContainsKey(argStr))
            {
                return(instMap[argStr]);
            }
            else
            {
                GenericMethodInstanceReference newInstMethRef = new GenericMethodInstanceReference(templateMeth,
                                                                                                   genericArgs, internFactory);
                IMethodDefinition newInstMeth = newInstMethRef.ResolvedMethod;
                instMap[argStr] = newInstMeth;
                return(newInstMeth);
            }
        }
Example #7
0
        private void NoteGenericParameterFlowForMethod(IMethodDefinition calledMethod)
        {
            // There are three ways generic parameters can flow
            //
            // 1) generic type parameters via a newobject constructor
            // 2) generic type parameters via a static call
            // 3) generic method parameters via a (non-constructor)method call

            // t-devinc:
            // I don't think this handles specialized types properly (i.e. a type some of whose parameters are instantiated
            // and some of whom are generic). This can happen with inner classes.


            // handle Foo<T>.DoSomething(); or new Foo<T>()
            if (calledMethod.ContainingTypeDefinition is IGenericTypeInstance && (calledMethod.IsStatic || calledMethod.IsConstructor))
            {
                IGenericTypeInstance instantiatedType = calledMethod.ContainingTypeDefinition as IGenericTypeInstance;

                ITypeDefinition genericType = instantiatedType.GenericType.ResolvedType;

                IEnumerable <ITypeReference> actuals = instantiatedType.GenericArguments;

                IEnumerable <IGenericParameter> formals = genericType.GenericParameters;

                NoteGenericParametersFlow(actuals, formals);
            }

            // handle Bar.DoSomething<T>();
            if (calledMethod is IGenericMethodInstance)
            {
                IGenericMethodInstance instantiatedMethod = calledMethod as IGenericMethodInstance;

                IMethodDefinition genericMethod = instantiatedMethod.GenericMethod.ResolvedMethod;

                IEnumerable <ITypeReference> actuals = instantiatedMethod.GenericArguments;

                IEnumerable <IGenericParameter> formals = genericMethod.GenericParameters;

                NoteGenericParametersFlow(actuals, formals);
            }
        }
            internal virtual void Visit(IOperation op)
            {
                IMethodDefinition target;

                switch (op.OperationCode)
                {
                case OperationCode.Newobj:
                    target = ResolveMethodReference(op.Value as IMethodReference);

                    if (target != null)
                    {
                        Contract.Assert(!(target is Dummy));

                        if (target.ContainingType is INamedTypeReference)
                        {
                            //Console.WriteLine("Got newobj to {0}", ((INamedTypeReference)target.ContainingType).Name);
                        }

                        ITypeDefinition constructedType = target.ContainingType.ResolvedType;
                        Contract.Assert(GarbageCollectHelper.TypeIsConstructable(constructedType));

                        summary.ReachableTypes.Add(constructedType);
                        summary.ConstructedTypes.Add(constructedType);
                        summary.NonvirtuallyCalledMethods.Add(target);
                    }
                    break;

                case OperationCode.Box:
                    // Boxing a struct means a callvirt could possibly
                    // dispatch to one of its methods.

                    ITypeDefinition boxedType = ResolveTypeReference(op.Value as ITypeReference);

                    if (boxedType != null)
                    {
                        // Guard for structs here because box to a reference type is a no-op but allowed and
                        // the Code Contracts instrumentation does this.
                        if (boxedType.IsStruct)
                        {
                            Contract.Assert(GarbageCollectHelper.TypeIsConstructable(boxedType));
                            summary.ConstructedTypes.Add(boxedType);
                        }
                    }
                    break;


                case OperationCode.Ldtoken:
                    if (op.Value is IFieldReference)
                    {
                        IFieldDefinition field = ResolveFieldReference(op.Value as IFieldReference);

                        if (field != null)
                        {
                            summary.ReachableFields.Add(field);
                        }
                    }

                    // t-devinc: Need to handle: method and type tokens, as well as generics.
                    // Fully supporting generics here may be very tricky -- this is a place
                    // where operating over specialized bytecode could perhaps help.
                    break;

                /* Notes on call/callvirt:
                 *
                 * We can get a call on a virtual method when that method is called via 'base'
                 * We can also get a callvirt on a non-virtual method whenever the compiler
                 * feels like it? This seems a little wonky.
                 */
                case OperationCode.Ldftn:
                case OperationCode.Call:
                    target = ResolveMethodReference(op.Value as IMethodReference);

                    if (target != null)
                    {
                        if (target.ContainingType is INamedTypeReference)
                        {
                            //Console.WriteLine("Got call to {0}", target);
                        }

                        summary.NonvirtuallyCalledMethods.Add(target);

                        if (target.Name.Value == "CreateInstance")
                        {
                            // t-devinc: gross, clean this up

                            INamespaceTypeDefinition containingTypeDefinition = target.ContainingTypeDefinition as INamespaceTypeDefinition;
                            if (containingTypeDefinition != null && containingTypeDefinition.Name.Value == "Activator")
                            {
                                if (containingTypeDefinition.ContainingNamespace.Name.Value == "System")
                                {
                                    IGenericMethodInstance targetAsGenericMethodInstance = target as IGenericMethodInstance;

                                    if (targetAsGenericMethodInstance != null)
                                    {
                                        // We have a call to 'new T()';
                                        ITypeDefinition definitionForT = targetAsGenericMethodInstance.GenericArguments.First().ResolvedType;

                                        summary.ConstructedTypeParameters.Add((IGenericParameter)definitionForT);
                                    }
                                }
                            }
                        }
                    }
                    break;

                case OperationCode.Ldvirtftn:
                case OperationCode.Callvirt:

                    target = ResolveMethodReference(op.Value as IMethodReference);

                    if (target != null)
                    {
                        if (target.ContainingType is INamedTypeReference)
                        {
                            //Console.WriteLine("Got callvirt to {0}", target);
                        }

                        if (target.IsVirtual)
                        {
                            summary.VirtuallyCalledMethods.Add(target);
                        }
                        else
                        {
                            // In its infinite wisdom, sometimes the compiler gives us a callvirt on a non-virtual method

                            summary.NonvirtuallyCalledMethods.Add(target);
                        }
                    }
                    break;

                case OperationCode.Ldfld:
                case OperationCode.Ldflda:
                case OperationCode.Ldsfld:
                case OperationCode.Ldsflda:

                /* For now we treat loads and stores as the same -- we'll want to be smarter about this in the future */
                case OperationCode.Stfld:
                case OperationCode.Stsfld:
                    IFieldDefinition fieldDefinition = ResolveFieldReference(op.Value as IFieldReference);

                    if (fieldDefinition != null)
                    {
                        summary.ReachableTypes.Add(fieldDefinition.ContainingTypeDefinition);
                        summary.ReachableFields.Add(fieldDefinition);
                    }
                    break;

                default:
                    break;
                }
            }
Example #9
0
        public void SaveScope(IMetadataHost host)
        {
            string                 modulesFN      = "modules.txt";
            StreamWriter           modulesSW      = new StreamWriter(Path.Combine(ConfigParams.SaveScopePath, modulesFN));
            List <IModule>         moduleList     = host.LoadedUnits.OfType <IModule>().ToList();
            TypeDefinitionComparer tdc            = new TypeDefinitionComparer();
            ISet <ITypeDefinition> processedTypes = new HashSet <ITypeDefinition>(tdc);

            foreach (IModule module in moduleList)
            {
                if (module == null || module == Dummy.Module || module == Dummy.Assembly)
                {
                    System.Console.WriteLine("WARNING: SaveScope - modules: Dummy or null module - skipping.");
                    continue;
                }
                modulesSW.WriteLine("MODULE:" + module.Name.Value + " LOCATION:" + module.Location);
            }
            modulesSW.Close();

            string       classesFN = "classes.txt";
            StreamWriter classesSW = new StreamWriter(Path.Combine(ConfigParams.SaveScopePath, classesFN));

            foreach (ITypeDefinition cl in classes)
            {
                if (processedTypes.Contains(cl))
                {
                    continue;
                }
                IModule mod = TypeHelper.GetDefiningUnit(cl) as IModule;
                if (cl is IGenericTypeInstance)
                {
                    ProcessGenericType(cl, classesSW, mod, processedTypes);
                }
                else
                {
                    classesSW.WriteLine("CLASS:" + cl.FullName() + " ARGS: MODULE:" + mod.Name.Value);
                    processedTypes.Add(cl);
                }
            }
            classesSW.Close();

            string       entClassesFN = "entrypt_classes.txt";
            StreamWriter entClassesSW = new StreamWriter(Path.Combine(ConfigParams.SaveScopePath, entClassesFN));

            foreach (ITypeDefinition cl in entryPtClasses)
            {
                IModule mod = TypeHelper.GetDefiningUnit(cl) as IModule;
                entClassesSW.WriteLine("CLASS:" + cl.FullName() + " ARGS: MODULE:" + mod.Name.Value);
            }
            entClassesSW.Close();

            string       methodsFN = "methods.txt";
            StreamWriter methodsSW = new StreamWriter(Path.Combine(ConfigParams.SaveScopePath, methodsFN));

            foreach (IMethodDefinition meth in methods)
            {
                string            argStr       = "";
                IMethodDefinition methToRecord = meth;
                if (meth is IGenericMethodInstance)
                {
                    IGenericMethodInstance       genericM    = meth as IGenericMethodInstance;
                    IEnumerable <ITypeReference> genericArgs = genericM.GenericArguments;
                    foreach (ITypeReference ty in genericArgs)
                    {
                        ITypeDefinition tyDefn = ty.ResolvedType;
                        argStr += tyDefn.FullName() + ";";
                    }
                    if (!argStr.Equals(""))
                    {
                        argStr = argStr.TrimEnd(';');
                    }
                    methToRecord = genericM.GenericMethod.ResolvedMethod;
                }
                methodsSW.WriteLine("METHOD:" + methToRecord.FullName() + " ARGS:" + argStr + " CLASS:" +
                                    methToRecord.ContainingTypeDefinition.FullName());
            }
            methodsSW.Close();
        }