/// <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>())) { ; } }
/// <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); }
/// <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)) { } }
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"); }
/// <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); }
/// <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); }
/// <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); } }
/// <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); } }
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(); }
/// <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)) { } }