public Action <ILNameSyntax> GetGenericTypeParameter(MetadataGenericContext genericContext, int index)
 {
     return(syntax => {
         output.Write("!");
         WriteTypeParameter(genericContext.GetGenericTypeParameterHandleOrNull(index), index, syntax);
     });
 }
Example #2
0
        /// <summary>
        /// </summary>
        /// <param name="method">
        /// </param>
        /// <param name="genericTypeSpecializations">
        /// </param>
        /// <param name="genericMethodSpecializations">
        /// </param>
        /// <param name="structTypes">
        /// </param>
        /// <param name="stackCall">
        /// </param>
        public static void DiscoverRequiredTypesAndMethodsInMethodBody(
            this IMethod method,
            ISet <IType> genericTypeSpecializations,
            ISet <IMethod> genericMethodSpecializations,
            ISet <IType> structTypes,
            ISet <IType> arrayTypes,
            Queue <IMethod> stackCall)
        {
            if (Il2Converter.VerboseOutput)
            {
                Debug.WriteLine("Scanning method for types: {0}", method);
            }

            // read method body to extract all types
            var reader = new IlReader();

            reader.UsedStructTypes = structTypes;
            reader.UsedArrayTypes  = arrayTypes;
            reader.UsedGenericSpecialiazedTypes   = genericTypeSpecializations;
            reader.UsedGenericSpecialiazedMethods = genericMethodSpecializations;

            var genericContext = MetadataGenericContext.DiscoverFrom(method, false); // true

            foreach (var op in reader.OpCodes(method, genericContext, stackCall))
            {
            }
        }
Example #3
0
 public ILStructure(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, ILStructureType type, int startOffset, int endOffset, ExceptionRegion handler = default)
 {
     Debug.Assert(startOffset < endOffset);
     this.Module           = module;
     this.MethodHandle     = handle;
     this.GenericContext   = genericContext;
     this.Type             = type;
     this.StartOffset      = startOffset;
     this.EndOffset        = endOffset;
     this.ExceptionHandler = handler;
 }
Example #4
0
 public ILStructure(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, ILStructureType type, int startOffset, int endOffset, int loopEntryPoint)
 {
     Debug.Assert(startOffset < endOffset);
     this.Module               = module;
     this.MethodHandle         = handle;
     this.GenericContext       = genericContext;
     this.Type                 = type;
     this.StartOffset          = startOffset;
     this.EndOffset            = endOffset;
     this.LoopEntryPointOffset = loopEntryPoint;
 }
Example #5
0
        private static IEnumerable <IType> GetAllRequiredTypesForMethod(
            IMethod method,
            ReadingTypesContext readingTypesContext)
        {
            DicoverGenericSpecializedTypesAndAdditionalTypes(
                method.ReturnType,
                readingTypesContext);

            foreach (var param in method.GetParameters())
            {
                DicoverGenericSpecializedTypesAndAdditionalTypes(
                    param.ParameterType,
                    readingTypesContext);
            }

            if (method.DeclaringType.IsInterface)
            {
                yield break;
            }

            var methodWithCustomBodyOrDefault = MethodBodyBank.GetMethodWithCustomBodyOrDefault(method, _codeWriter);
            var methodBody = methodWithCustomBodyOrDefault.GetMethodBody(MetadataGenericContext.DiscoverFrom(method));

            if (methodBody != null)
            {
                foreach (var localVar in methodBody.LocalVariables)
                {
                    DicoverGenericSpecializedTypesAndAdditionalTypes(
                        localVar.LocalType,
                        readingTypesContext);
                    if (localVar.LocalType.IsStructureType() && !localVar.LocalType.IsPointer && !localVar.LocalType.IsByRef)
                    {
                        yield return(localVar.LocalType);
                    }
                }

                var usedStructTypes = new NamespaceContainer <IType>();
                methodWithCustomBodyOrDefault.DiscoverRequiredTypesAndMethodsInMethodBody(
                    readingTypesContext.GenericTypeSpecializations,
                    readingTypesContext.GenericMethodSpecializations,
                    usedStructTypes,
                    readingTypesContext.AdditionalTypesToProcess,
                    new Queue <IMethod>());
                foreach (var usedStructType in usedStructTypes)
                {
                    yield return(usedStructType);
                }
            }
        }
Example #6
0
        /// <summary>
        /// </summary>
        /// <param name="method">
        /// </param>
        /// <param name="structTypes">
        /// </param>
        /// <param name="calledMethods">
        /// </param>
        /// <param name="readStaticFields">
        /// </param>
        public static void DiscoverMethod(this IMethod method, ISet <IType> structTypes, ISet <IMethod> calledMethods, ISet <IField> readStaticFields)
        {
            // read method body to extract all types
            var reader = new IlReader();

            reader.UsedTypes              = structTypes;
            reader.CalledMethods          = calledMethods;
            reader.UsedStaticFieldsToRead = readStaticFields;

            var genericContext = MetadataGenericContext.DiscoverFrom(method);

            foreach (var op in reader.OpCodes(method, genericContext, new Queue <IMethod>()))
            {
            }
        }
Example #7
0
        private static void DiscoverAllGenericMethodsOfInterfacesForMethod(IEnumerable <IType> allTypes, ISet <IMethod> genericMethodSpecializations, IGrouping <IType, IMethod> specializedTypeMethods)
        {
            var types = allTypes.Where(t => t.GetAllInterfaces().Contains(specializedTypeMethods.Key)).ToList();

            foreach (var specializedTypeMethod in specializedTypeMethods)
            {
                var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance;
                foreach (var genericMethodOfInterface in
                         types.SelectMany(t => t.GetMethods(flags).Where(m => m.IsGenericMethodDefinition && m.IsMatchingOverride(specializedTypeMethod))))
                {
                    genericMethodSpecializations.Add(
                        genericMethodOfInterface.ToSpecialization(MetadataGenericContext.CreateMap(genericMethodOfInterface, specializedTypeMethod)));
                }
            }
        }
Example #8
0
        internal void WriteExceptionHandlers(PEFile module, MethodDefinitionHandle handle, MethodBodyBlock body)
        {
            this.module      = module;
            metadata         = module.Metadata;
            genericContext   = new MetadataGenericContext(handle, module);
            signatureDecoder = new DisassemblerSignatureTypeProvider(module, output);
            var handlers = body.ExceptionRegions;

            if (!handlers.IsEmpty)
            {
                output.WriteLine();
                foreach (var eh in handlers)
                {
                    eh.WriteTo(module, genericContext, output);
                    output.WriteLine();
                }
            }
        }
Example #9
0
        /// <summary>
        /// </summary>
        /// <param name="allTypes">
        /// </param>
        /// <param name="genericMethodSpecializations">
        /// </param>
        private static void DiscoverAllGenericVirtualMethods(
            IEnumerable <IType> allTypes,
            ReadingTypesContext readingTypesContext)
        {
            var genericMethodSpecializations = readingTypesContext.GenericMethodSpecializations;

            // find all override of generic methods
            var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static |
                        BindingFlags.Instance;
            var overrideSpecializedMethods = new List <IMethod>();

            foreach (
                var overrideGenericMethod in
                allTypes.SelectMany(
                    t => t.GetMethods(flags).Where(m => m.IsOverride && m.IsGenericMethodDefinition)))
            {
                var method           = overrideGenericMethod;
                var methodDefinition = overrideGenericMethod;
                overrideSpecializedMethods.AddRange(
                    from methodSpecialization in
                    genericMethodSpecializations.Where(m => m.IsVirtual || m.IsOverride || m.IsAbstract)
                    where
                    method.DeclaringType.IsDerivedFrom(methodSpecialization.DeclaringType) &&
                    method.IsMatchingOverride(methodSpecialization)
                    select
                    methodDefinition.ToSpecialization(
                        MetadataGenericContext.CreateCustomMap(null, methodSpecialization, methodDefinition)));
            }

            // append to discovered
            foreach (var overrideSpecializedMethod in overrideSpecializedMethods)
            {
                genericMethodSpecializations.Add(overrideSpecializedMethod);

                // rediscover generic methods again
                overrideSpecializedMethod.DiscoverRequiredTypesAndMethodsInMethodBody(
                    readingTypesContext.GenericTypeSpecializations,
                    readingTypesContext.GenericMethodSpecializations,
                    null,
                    readingTypesContext.AdditionalTypesToProcess,
                    new Queue <IMethod>());
            }
        }
Example #10
0
        /// <summary>
        /// </summary>
        /// <param name="method">
        /// </param>
        /// <param name="genericTypeSpecializations">
        /// </param>
        /// <param name="genericMethodSpecializations">
        /// </param>
        /// <param name="requiredTypes">
        /// </param>
        /// <param name="stackCall">
        /// </param>
        public static void DiscoverRequiredTypesAndMethodsInMethodBody(
            this IMethod method,
            ISet <IType> genericTypeSpecializations,
            ISet <IMethod> genericMethodSpecializations,
            ISet <IType> requiredTypes,
            Queue <IMethod> stackCall)
        {
            // read method body to extract all types
            var reader = new IlReader();

            reader.UsedStructTypes = requiredTypes;
            reader.UsedGenericSpecialiazedTypes   = genericTypeSpecializations;
            reader.UsedGenericSpecialiazedMethods = genericMethodSpecializations;

            var genericContext = MetadataGenericContext.DiscoverFrom(method, false); // true

            foreach (var op in reader.OpCodes(method, genericContext, stackCall))
            {
            }
        }
Example #11
0
        private static void DiscoverAllGenericMethodsOfInterfacesForMethod(
            IEnumerable <IType> allTypes,
            IGrouping <IType, IMethod> specializedTypeMethods,
            ReadingTypesContext readingTypesContext)
        {
            var types = allTypes.Where(t => t.GetAllInterfaces().Contains(specializedTypeMethods.Key)).ToList();

            foreach (var interfaceMethodSpecialization in specializedTypeMethods)
            {
                var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance;
                foreach (var classMethodDefinition in
                         types.SelectMany(
                             t =>
                             t.GetMethods(flags)
                             .Where(m => m.IsGenericMethodDefinition && m.IsMatchingOverride(interfaceMethodSpecialization))))
                {
                    // find interface
                    var @interfaceDefinition =
                        classMethodDefinition.DeclaringType.GetInterfaces()
                        .First(i => i.TypeEquals(interfaceMethodSpecialization.DeclaringType));

                    var @interfaceMethodDefinition = @interfaceDefinition.GetMethods(flags)
                                                     .First(m => m.IsGenericMethodDefinition && m.IsMatchingOverride(interfaceMethodSpecialization));

                    var classMethodSpecialization =
                        classMethodDefinition.ToSpecialization(
                            MetadataGenericContext.CreateCustomMap(@interfaceMethodDefinition, interfaceMethodSpecialization, classMethodDefinition));

                    readingTypesContext.GenericMethodSpecializations.Add(classMethodSpecialization);

                    // rediscover generic methods again
                    classMethodSpecialization.DiscoverRequiredTypesAndMethodsInMethodBody(
                        readingTypesContext.GenericTypeSpecializations,
                        readingTypesContext.GenericMethodSpecializations,
                        null,
                        readingTypesContext.AdditionalTypesToProcess,
                        new Queue <IMethod>());
                }
            }
        }
Example #12
0
        /// <summary>
        /// </summary>
        /// <param name="allTypes">
        /// </param>
        /// <param name="genericMethodSpecializations">
        /// </param>
        private static void DiscoverAllGenericVirtualMethods(IEnumerable <IType> allTypes, ISet <IMethod> genericMethodSpecializations)
        {
            // find all override of generic methods
            var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
            var overrideSpecializedMethods = new List <IMethod>();

            foreach (var overrideGenericMethod in allTypes.SelectMany(t => t.GetMethods(flags).Where(m => m.IsOverride && m.IsGenericMethodDefinition)))
            {
                var method        = overrideGenericMethod;
                var genericMethod = overrideGenericMethod;
                overrideSpecializedMethods.AddRange(
                    from specializationMethod in genericMethodSpecializations.Where(m => m.IsVirtual || m.IsOverride || m.IsAbstract)
                    where method.DeclaringType.IsDerivedFrom(specializationMethod.DeclaringType) && method.IsMatchingOverride(specializationMethod)
                    select genericMethod.ToSpecialization(MetadataGenericContext.CreateMap(genericMethod, specializationMethod)));
            }

            // append to discovered
            foreach (var overrideSpecializedMethod in overrideSpecializedMethods)
            {
                genericMethodSpecializations.Add(overrideSpecializedMethod);
            }
        }
Example #13
0
        /// <summary>
        /// </summary>
        /// <param name="type">
        /// </param>
        /// <param name="genericTypeSpecializations">
        /// </param>
        /// <param name="genericMethodSpecializations">
        /// </param>
        /// <returns>
        /// </returns>
        private static IEnumerable <IType> GetAllRequiredITypesForIType(
            IType type, ISet <IType> genericTypeSpecializations, ISet <IMethod> genericMethodSpecializations)
        {
            Debug.Assert(type != null);

            if (type.BaseType != null)
            {
                DicoverGenericSpecializedIType(type.BaseType, genericTypeSpecializations, genericMethodSpecializations);
                yield return(type.BaseType);
            }

            var interfaces = type.GetInterfaces();

            if (interfaces != null)
            {
                foreach (var @interface in interfaces)
                {
                    DicoverGenericSpecializedIType(@interface, genericTypeSpecializations, genericMethodSpecializations);
                    yield return(@interface);
                }
            }

            var fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            if (fields != null)
            {
                foreach (var field in fields)
                {
                    DicoverGenericSpecializedIType(field.FieldType, genericTypeSpecializations, genericMethodSpecializations);
                    if (field.FieldType.IsStructureType() && !field.FieldType.IsPointer)
                    {
                        yield return(field.FieldType);
                    }
                }
            }

            var methods = type.GetMethods(
                BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            if (methods != null)
            {
                foreach (var method in methods)
                {
                    DicoverGenericSpecializedIType(method.ReturnType, genericTypeSpecializations, genericMethodSpecializations);

                    foreach (var param in method.GetParameters())
                    {
                        DicoverGenericSpecializedIType(param.ParameterType, genericTypeSpecializations, genericMethodSpecializations);
                    }

                    var methodBody = method.GetMethodBody(MetadataGenericContext.DiscoverFrom(method));
                    if (methodBody != null)
                    {
                        foreach (var localVar in methodBody.LocalVariables)
                        {
                            DicoverGenericSpecializedIType(localVar.LocalType, genericTypeSpecializations, genericMethodSpecializations);
                            if (localVar.LocalType.IsStructureType() && !localVar.LocalType.IsPointer)
                            {
                                yield return(localVar.LocalType);
                            }
                        }

                        var usedStructTypes = new HashSet <IType>();
                        method.DiscoverRequiredTypesAndMethodsInMethodBody(
                            genericTypeSpecializations, genericMethodSpecializations, usedStructTypes, new Queue <IMethod>());
                        foreach (var usedStructType in usedStructTypes)
                        {
                            yield return(usedStructType);
                        }
                    }
                }
            }
        }
Example #14
0
        /// <summary>
        /// </summary>
        /// <param name="ilReader">
        /// </param>
        /// <param name="codeWriter">
        /// </param>
        /// <param name="type">
        /// </param>
        /// <param name="genericDefinition">
        /// </param>
        /// <param name="genericMethodSpecializatons">
        /// </param>
        /// <param name="mode">
        /// </param>
        /// <param name="processGenericMethodsOnly">
        /// </param>
        private static void ConvertIType(
            IlReader ilReader,
            ICodeWriter codeWriter,
            IType type,
            IType genericDefinition,
            IEnumerable <IMethod> genericMethodSpecializatons,
            ConvertingMode mode,
            bool processGenericMethodsOnly = false)
        {
            Debug.WriteLine("Converting {0}, Mode: {1}", type, mode);

            var typeSpecialization = type.IsGenericType && !type.IsGenericTypeDefinition ? type : null;

            var genericContext = new MetadataGenericContext();

            genericContext.TypeDefinition       = genericDefinition;
            genericContext.TypeSpecialization   = typeSpecialization;
            genericContext.MethodDefinition     = null;
            genericContext.MethodSpecialization = null;

            if (mode == ConvertingMode.Declaration)
            {
                if (!codeWriter.IsProcessed(type))
                {
                    WriteTypeDefinition(codeWriter, type, genericContext);
                }

                codeWriter.WritePostDeclarations(type);

                codeWriter.WriteBeforeConstructors();
            }

            if (mode == ConvertingMode.Definition)
            {
                codeWriter.DisableWrite(true);

                if (!processGenericMethodsOnly)
                {
                    // pre process step to get all used undefined structures
                    foreach (var ctor in IlReader.Constructors(type))
                    {
                        IConstructor genericCtor = null;
                        if (type.IsGenericType && !type.IsInterface && !type.IsDelegate)
                        {
                            // find the same constructor in generic class
                            Debug.Assert(genericDefinition != null);
                            genericCtor = IlReader.Constructors(genericDefinition).First(gm => ctor.IsMatchingGeneric(gm));
                        }

                        genericContext.MethodDefinition     = genericCtor;
                        genericContext.MethodSpecialization = null;

                        codeWriter.WriteConstructorStart(ctor, genericContext);

                        foreach (var ilCode in ilReader.OpCodes(genericCtor ?? ctor, genericContext))
                        {
                            codeWriter.Write(ilCode);
                        }

                        codeWriter.WriteConstructorEnd(ctor, genericContext);
                    }
                }

                codeWriter.DisableWrite(false);

                // Actual Write
                codeWriter.WriteRequiredTypesForBody();
                codeWriter.WriteStoredText();
            }

            if (mode == ConvertingMode.Declaration)
            {
                codeWriter.WriteAfterConstructors();
                codeWriter.WriteBeforeMethods();
            }

            if (mode == ConvertingMode.Definition)
            {
                codeWriter.DisableWrite(true);

                // pre process step to get all used undefined structures
                foreach (var method in IlReader.MethodsOriginal(type).Select(m => MethodBodyBank.GetMethodBodyOrDefault(m, codeWriter)))
                {
                    IMethod genericMethod = null;
                    if (type.IsGenericType && !type.IsInterface && !type.IsDelegate)
                    {
                        // find the same method in generic class
                        genericMethod = IlReader.MethodsOriginal(genericDefinition).First(gm => method.IsMatchingGeneric(gm.ToSpecialization(genericContext)));
                    }

                    if (!method.IsGenericMethodDefinition && !processGenericMethodsOnly)
                    {
                        genericContext.MethodDefinition     = genericMethod;
                        genericContext.MethodSpecialization = genericMethod != null ? method : null;

                        codeWriter.WriteMethodStart(method, genericContext);

                        foreach (var ilCode in ilReader.OpCodes(genericMethod ?? method, genericContext))
                        {
                            codeWriter.Write(ilCode);
                        }

                        codeWriter.WriteMethodEnd(method, genericContext);
                    }
                    else
                    {
                        // write all specializations of a method
                        if (genericMethodSpecializatons != null)
                        {
                            foreach (var methodSpec in genericMethodSpecializatons)
                            {
                                if (!methodSpec.IsMatchingGeneric(method))
                                {
                                    continue;
                                }

                                genericContext.MethodDefinition     = method;
                                genericContext.MethodSpecialization = methodSpec;

                                codeWriter.WriteMethodStart(methodSpec, genericContext);

                                foreach (var ilCode in ilReader.OpCodes(genericMethod ?? method, genericContext))
                                {
                                    codeWriter.Write(ilCode);
                                }

                                codeWriter.WriteMethodEnd(methodSpec, genericContext);
                            }
                        }
                    }
                }

                codeWriter.DisableWrite(false);

                // Actual Write
                codeWriter.WriteRequiredTypesForBody();
                codeWriter.WriteStoredText();
            }

            if (mode == ConvertingMode.Declaration)
            {
                codeWriter.WriteAfterMethods();
                codeWriter.WriteTypeEnd(type);
            }
        }
Example #15
0
        /// <summary>
        /// </summary>
        /// <param name="ilReader">
        /// </param>
        /// <param name="codeWriter">
        /// </param>
        /// <param name="type">
        /// </param>
        /// <param name="typeDefinition">
        /// </param>
        /// <param name="genericMethodSpecializatons">
        /// </param>
        /// <param name="mode">
        /// </param>
        /// <param name="processGenericMethodsOnly">
        /// </param>
        private static void ConvertIType(
            IlReader ilReader,
            ICodeWriter codeWriter,
            IType type,
            IEnumerable <IMethod> genericMethodSpecializatons,
            ConvertingMode mode,
            bool processGenericMethodsOnly = false)
        {
            if (VerboseOutput)
            {
                Trace.WriteLine(string.Format("Converting {0}, Mode: {1}", type, mode));
            }

            var typeDefinition     = type.IsGenericType ? type.GetTypeDefinition() : null;
            var typeSpecialization = type.IsGenericType && !type.IsGenericTypeDefinition ? type : null;
            var genericTypeContext = typeDefinition != null || typeSpecialization != null
                                         ? MetadataGenericContext.Create(typeDefinition, typeSpecialization)
                                         : null;

            if (mode == ConvertingMode.Declaration)
            {
                if (!codeWriter.IsProcessed(type))
                {
                    WriteTypeDefinition(codeWriter, type, genericTypeContext);
                }

                codeWriter.WritePostDeclarationsAndInternalDefinitions(type);

                codeWriter.WriteBeforeConstructors();
            }

            if (mode == ConvertingMode.Definition)
            {
                codeWriter.DisableWrite(true);

                if (!processGenericMethodsOnly)
                {
                    // pre process step to get all used undefined structures
                    foreach (var ctor in IlReader.Constructors(type, codeWriter))
                    {
                        codeWriter.WriteConstructorStart(ctor, genericTypeContext);

                        foreach (var ilCode in ilReader.OpCodes(type.IsGenericType ? ctor.GetMethodDefinition() : ctor, genericTypeContext))
                        {
                            codeWriter.Write(ilCode);
                        }

                        codeWriter.WriteConstructorEnd(ctor, genericTypeContext);
                    }
                }

                codeWriter.DisableWrite(false);

                // Actual Write
                codeWriter.WriteRequiredTypesForBody();
                codeWriter.WriteStoredText();
            }

            if (mode == ConvertingMode.Declaration)
            {
                codeWriter.WriteAfterConstructors();
                codeWriter.WriteBeforeMethods();
            }

            if (mode == ConvertingMode.Definition)
            {
                codeWriter.DisableWrite(true);

                // pre process step to get all used undefined structures
                foreach (
                    var method in
                    IlReader.Methods(type, codeWriter, true).Select(m => MethodBodyBank.GetMethodWithCustomBodyOrDefault(m, codeWriter)))
                {
                    if (!method.IsGenericMethodDefinition && !processGenericMethodsOnly)
                    {
                        var genericMethodContext = method.IsGenericMethod
                                                       ? MetadataGenericContext.Create(typeDefinition, typeSpecialization, method.GetMethodDefinition(), method)
                                                       : genericTypeContext;

                        codeWriter.WriteMethodStart(method, genericMethodContext);

                        foreach (var ilCode in ilReader.OpCodes(type.IsGenericType ? method.GetMethodDefinition() : method, genericMethodContext))
                        {
                            codeWriter.Write(ilCode);
                        }

                        codeWriter.WriteMethodEnd(method, genericMethodContext);
                    }

                    if (method.IsGenericMethodDefinition || method.IsGenericMethod)
                    {
                        // write all specializations of a method
                        if (genericMethodSpecializatons != null)
                        {
                            var methodDefinition = method.GetMethodDefinition();
                            foreach (
                                var methodSpec in
                                genericMethodSpecializatons.Where(
                                    methodSpec => methodSpec.IsMatchingGeneric(methodDefinition) && (!methodSpec.Equals(method) || processGenericMethodsOnly)))
                            {
                                var genericMethodContext = MetadataGenericContext.Create(typeDefinition, typeSpecialization, method, methodSpec);

                                codeWriter.WriteMethodStart(methodSpec, genericMethodContext);

                                foreach (var ilCode in ilReader.OpCodes(methodDefinition ?? method, genericMethodContext))
                                {
                                    codeWriter.Write(ilCode);
                                }

                                codeWriter.WriteMethodEnd(methodSpec, genericMethodContext);
                            }
                        }
                    }
                }

                codeWriter.DisableWrite(false);

                // Actual Write
                codeWriter.WriteRequiredTypesForBody();
                codeWriter.WriteStoredText();
            }

            if (mode == ConvertingMode.Declaration)
            {
                codeWriter.WriteAfterMethods();
                codeWriter.WriteTypeEnd(type);
            }
        }
Example #16
0
        public ILStructure(PEFile module, MethodDefinitionHandle handle, MetadataGenericContext genericContext, MethodBodyBlock body)
            : this(module, handle, genericContext, ILStructureType.Root, 0, body.GetILReader().Length)
        {
            // Build the tree of exception structures:
            for (int i = 0; i < body.ExceptionRegions.Length; i++)
            {
                ExceptionRegion eh = body.ExceptionRegions[i];
                if (!body.ExceptionRegions.Take(i).Any(oldEh => oldEh.TryOffset == eh.TryOffset && oldEh.TryLength == eh.TryLength))
                {
                    AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Try, eh.TryOffset, eh.TryOffset + eh.TryLength, eh));
                }
                if (eh.Kind == ExceptionRegionKind.Filter)
                {
                    AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Filter, eh.FilterOffset, eh.HandlerOffset, eh));
                }
                AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Handler, eh.HandlerOffset, eh.HandlerOffset + eh.HandlerLength, eh));
            }
            // Very simple loop detection: look for backward branches
            (var allBranches, var isAfterUnconditionalBranch) = FindAllBranches(body.GetILReader());
            // We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;")
            for (int i = allBranches.Count - 1; i >= 0; i--)
            {
                int loopEnd   = allBranches[i].Source.End;
                int loopStart = allBranches[i].Target;
                if (loopStart < loopEnd)
                {
                    // We found a backward branch. This is a potential loop.
                    // Check that is has only one entry point:
                    int entryPoint = -1;

                    // entry point is first instruction in loop if prev inst isn't an unconditional branch
                    if (loopStart > 0 && !isAfterUnconditionalBranch[loopStart])
                    {
                        entryPoint = allBranches[i].Target;
                    }

                    bool multipleEntryPoints = false;
                    foreach (var branch in allBranches)
                    {
                        if (branch.Source.Start < loopStart || branch.Source.Start >= loopEnd)
                        {
                            if (loopStart <= branch.Target && branch.Target < loopEnd)
                            {
                                // jump from outside the loop into the loop
                                if (entryPoint < 0)
                                {
                                    entryPoint = branch.Target;
                                }
                                else if (branch.Target != entryPoint)
                                {
                                    multipleEntryPoints = true;
                                }
                            }
                        }
                    }
                    if (!multipleEntryPoints)
                    {
                        AddNestedStructure(new ILStructure(module, handle, genericContext, ILStructureType.Loop, loopStart, loopEnd, entryPoint));
                    }
                }
            }
            SortChildren();
        }
Example #17
0
        public virtual void Disassemble(PEFile module, MethodDefinitionHandle handle)
        {
            this.module      = module ?? throw new ArgumentNullException(nameof(module));
            metadata         = module.Metadata;
            genericContext   = new MetadataGenericContext(handle, module);
            signatureDecoder = new DisassemblerSignatureTypeProvider(module, output);
            var methodDefinition = metadata.GetMethodDefinition(handle);

            // start writing IL code
            output.WriteLine("// Method begins at RVA 0x{0:x4}", methodDefinition.RelativeVirtualAddress);
            if (methodDefinition.RelativeVirtualAddress == 0)
            {
                output.WriteLine("// Header size: {0}", 0);
                output.WriteLine("// Code size: {0} (0x{0:x})", 0);
                output.WriteLine(".maxstack {0}", 0);
                output.WriteLine();
                return;
            }
            MethodBodyBlock body;
            BlobReader      bodyBlockReader;

            try
            {
                body            = module.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress);
                bodyBlockReader = module.Reader.GetSectionData(methodDefinition.RelativeVirtualAddress).GetReader();
            }
            catch (BadImageFormatException ex)
            {
                output.WriteLine("// {0}", ex.Message);
                return;
            }
            var blob       = body.GetILReader();
            int headerSize = ILParser.GetHeaderSize(bodyBlockReader);

            output.WriteLine("// Header size: {0}", headerSize);
            output.WriteLine("// Code size: {0} (0x{0:x})", blob.Length);
            output.WriteLine(".maxstack {0}", body.MaxStack);

            var entrypointHandle = MetadataTokens.MethodDefinitionHandle(module.Reader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress);

            if (handle == entrypointHandle)
            {
                output.WriteLine(".entrypoint");
            }

            DisassembleLocalsBlock(handle, body);
            output.WriteLine();

            sequencePoints         = DebugInfo?.GetSequencePoints(handle) ?? EmptyList <DebugInfo.SequencePoint> .Instance;
            nextSequencePointIndex = 0;
            if (DetectControlStructure && blob.Length > 0)
            {
                blob.Reset();
                HashSet <int> branchTargets = GetBranchTargets(blob);
                blob.Reset();
                WriteStructureBody(new ILStructure(module, handle, genericContext, body), branchTargets, ref blob, methodDefinition.RelativeVirtualAddress + headerSize);
            }
            else
            {
                while (blob.RemainingBytes > 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    WriteInstruction(output, metadata, handle, ref blob, methodDefinition.RelativeVirtualAddress);
                }
                WriteExceptionHandlers(module, handle, body);
            }
            sequencePoints = null;
        }
 public Action <ILNameSyntax> GetTypeFromSpecification(MetadataReader reader, MetadataGenericContext genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
 {
     return(reader.GetTypeSpecification(handle).DecodeSignature(this, genericContext));
 }
Example #19
0
 public static void WriteTo(this SRM.ExceptionRegion exceptionHandler, Metadata.PEFile module, MetadataGenericContext context, ITextOutput writer)
 {
     writer.Write(".try ");
     WriteOffsetReference(writer, exceptionHandler.TryOffset);
     writer.Write('-');
     WriteOffsetReference(writer, exceptionHandler.TryOffset + exceptionHandler.TryLength);
     writer.Write(' ');
     writer.Write(exceptionHandler.Kind.ToString().ToLowerInvariant());
     if (exceptionHandler.FilterOffset != -1)
     {
         writer.Write(' ');
         WriteOffsetReference(writer, exceptionHandler.FilterOffset);
         writer.Write(" handler ");
     }
     if (!exceptionHandler.CatchType.IsNil)
     {
         writer.Write(' ');
         exceptionHandler.CatchType.WriteTo(module, writer, context);
     }
     writer.Write(' ');
     WriteOffsetReference(writer, exceptionHandler.HandlerOffset);
     writer.Write('-');
     WriteOffsetReference(writer, exceptionHandler.HandlerOffset + exceptionHandler.HandlerLength);
 }