예제 #1
0
        /// <summary>
        /// </summary>
        /// <param name="method">
        /// </param>
        /// <param name="usedTypes">
        /// </param>
        /// <param name="calledMethods">
        /// </param>
        /// <param name="readStaticFields">
        /// </param>
        public static void DiscoverMethod(this IMethod method, ISet<IType> usedTypes, ISet<IMethod> calledMethods, ISet<IField> readStaticFields)
        {
            // read method body to extract all types
            var reader = new IlReader();

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

            var genericContext = MetadataGenericContext.DiscoverFrom(method);
            foreach (var op in reader.OpCodes(method, genericContext, new Queue<IMethod>()))
            {
                ;
            }
        }
예제 #2
0
        /// <summary>
        /// </summary>
        /// <param name="sources">
        /// </param>
        /// <param name="outputFolder">
        /// </param>
        /// <param name="args">
        /// </param>
        public static void Convert(string[] sources, string outputFolder, string[] args = null, string[] filter = null)
        {
            var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(sources.First());

            var ilReader = new IlReader(sources, args);
            ilReader.Load();

            GenerateLlvm(
                ilReader,
                fileNameWithoutExtension,
                ilReader.SourceFilePath,
                ilReader.PdbFilePath,
                outputFolder,
                args,
                filter);
        }
예제 #3
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))
            {
            }
        }
예제 #4
0
        private static void ReadingTypes(
            IlReader ilReader,
            string[] filter,
            out IList<IType> usedTypes,
            out IDictionary<IType, IEnumerable<IMethod>> genericMethodSpecializationsSorted)
        {
            // clean it as you are using IlReader
            IlReader.GenericMethodSpecializations = null;

            // types in current assembly
            var readingTypesContext = ReadingTypesContext.New();
            var types = ilReader.Types().Where(t => !t.IsGenericTypeDefinition);
            if (filter != null)
            {
                types = types.Where(t => CheckFilter(filter, t));
            }

            var allTypes = ilReader.AllTypes().ToList();

            // TODO: temp hack to initialize ThisType for TypeResolver
            _codeWriter.Initialize(allTypes.First());

            usedTypes = FindUsedTypes(types.ToList(), allTypes, readingTypesContext);

            genericMethodSpecializationsSorted = GroupGenericMethodsByType(readingTypesContext.GenericMethodSpecializations);

            Debug.Assert(usedTypes.All(t => !t.IsByRef), "Type is used with flag IsByRef");
        }
예제 #5
0
        /// <summary>
        /// </summary>
        /// <param name="ilReader">
        /// </param>
        /// <param name="filter">
        /// </param>
        /// <param name="codeWriter">
        /// </param>
        private static void GenerateSource(IlReader ilReader, string[] filter, ICodeWriter codeWriter)
        {
            _codeWriter = codeWriter;

            cachedRequiredTypes.Clear();

            IList<IType> sortedListOfTypes;
            IDictionary<IType, IEnumerable<IMethod>> genericMethodSpecializationsSorted;
            ReadingTypes(
                ilReader,
                filter,
                out sortedListOfTypes,
                out genericMethodSpecializationsSorted);

            Writing(
                ilReader,
                codeWriter,
                sortedListOfTypes,
                genericMethodSpecializationsSorted);
        }
예제 #6
0
 /// <summary>
 /// </summary>
 /// <param name="ilReader">
 /// </param>
 /// <param name="fileName">
 /// </param>
 /// <param name="outputFolder">
 /// </param>
 /// <param name="args">
 /// </param>
 /// <param name="filter">
 /// </param>
 private static void GenerateLlvm(
     IlReader ilReader,
     string fileName,
     string sourceFilePath,
     string pdbFilePath,
     string outputFolder,
     string[] args,
     string[] filter = null)
 {
     concurrent = args != null && args.Any(a => a == "multi");
     VerboseOutput = args != null && args.Any(a => a == "verbose");
     var codeWriter = GetLlvmWriter(fileName, sourceFilePath, pdbFilePath, outputFolder, args);
     GenerateSource(ilReader, filter, codeWriter);
 }
예제 #7
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);
            }
        }
예제 #8
0
        /// <summary>
        /// </summary>
        /// <param name="ilReader">
        /// </param>
        /// <param name="filter">
        /// </param>
        /// <param name="codeWriter">
        /// </param>
        /// <param name="newListOfITypes">
        /// </param>
        /// <param name="genDefinitionsByMetadataName">
        /// </param>
        /// <param name="genMethodSpec">
        /// </param>
        /// <param name="mode">
        /// </param>
        /// <param name="processGenericMethodsOnly">
        /// </param>
        private static void ConvertAllTypes(
            IlReader ilReader,
            ICodeWriter codeWriter,
            IList<IType> newListOfITypes,
            IDictionary<IType, IEnumerable<IMethod>> genMethodSpec,
            ConvertingMode mode,
            bool processGenericMethodsOnly = false)
        {
            foreach (var type in newListOfITypes)
            {
                Debug.Assert(type != null);
                if (type == null)
                {
                    continue;
                }

                if (type.IsGenericTypeDefinition)
                {
                    continue;
                }

                if (type.FullName == "<Module>")
                {
                    continue;
                }

                IEnumerable<IMethod> genericMethodSpecializatonsForType = null;
                genMethodSpec.TryGetValue(type, out genericMethodSpecializatonsForType);

                ConvertIType(
                    ilReader,
                    codeWriter,
                    type.ToClass(),
                    genericMethodSpecializatonsForType,
                    mode,
                    processGenericMethodsOnly);
            }
        }
예제 #9
0
        private static void Writing(
            IlReader ilReader,
            ICodeWriter codeWriter,
            IList<IType> newListOfITypes,
            IDictionary<IType, IEnumerable<IMethod>> genericMethodSpecializationsSorted)
        {
            // writing
            codeWriter.WriteStart(ilReader);

            WriteForwardDeclarations(codeWriter, newListOfITypes);

            ConvertAllTypes(
                ilReader,
                codeWriter,
                newListOfITypes,
                genericMethodSpecializationsSorted,
                ConvertingMode.Declaration);

            ConvertAllTypes(
                ilReader,
                codeWriter,
                newListOfITypes,
                genericMethodSpecializationsSorted,
                ConvertingMode.Definition);

            // Append definition of Generic Methods of not used non-generic types
            ConvertAllTypes(
                ilReader,
                codeWriter,
                genericMethodSpecializationsSorted.Keys.Where(k => !newListOfITypes.Contains(k)).ToList(),
                genericMethodSpecializationsSorted,
                ConvertingMode.Definition,
                true);

            codeWriter.WriteEnd();

            codeWriter.Close();
        }
예제 #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))
            {
            }
        }