/// <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"); var codeWriter = GetLlvmWriter(fileName, sourceFilePath, pdbFilePath, outputFolder, args); GenerateSource(ilReader, filter, codeWriter); }
private static void Writing(IlReader ilReader, string[] filter, ICodeWriter codeWriter, List <IType> newListOfITypes, SortedDictionary <string, IType> genDefinitionsByMetadataName, SortedDictionary <IType, IEnumerable <IMethod> > genericMethodSpecializationsSorted) { // writing codeWriter.WriteStart(ilReader.ModuleName, ilReader.AssemblyQualifiedName, ilReader.IsCoreLib, ilReader.AllReferences()); WriteForwardDeclarations(codeWriter, newListOfITypes); ConvertAllTypes( ilReader, filter, codeWriter, newListOfITypes, genDefinitionsByMetadataName, genericMethodSpecializationsSorted, ConvertingMode.Declaration); ConvertAllTypes( ilReader, filter, codeWriter, newListOfITypes, genDefinitionsByMetadataName, genericMethodSpecializationsSorted, ConvertingMode.Definition); // Append definition of Generic Methods of not used non-generic types ConvertAllTypes( ilReader, filter, codeWriter, genericMethodSpecializationsSorted.Keys.Where(k => !newListOfITypes.Contains(k)).ToList(), genDefinitionsByMetadataName, genericMethodSpecializationsSorted, ConvertingMode.Definition, true); codeWriter.WriteEnd(); codeWriter.Close(); }
/// <summary> /// </summary> /// <param name="virtualTable"> /// </param> /// <param name="interface"> /// </param> /// <param name="allPublic"> /// </param> private static void AddMethodsToVirtualInterfaceTable( this List <LlvmWriter.Pair <IMethod, IMethod> > virtualTable, IType @interface, IEnumerable <IMethod> allPublic, ITypeResolver typeResolver) { var allInterfaces = @interface.GetInterfaces(); var firstChildInterface = allInterfaces != null?allInterfaces.FirstOrDefault() : null; if (firstChildInterface != null) { // get all virtual methods in current type and replace or append virtualTable.AddMethodsToVirtualInterfaceTable(firstChildInterface, allPublic, typeResolver); } // get all virtual methods in current type and replace or append #if DEBUG var interfaceMethods = IlReader.Methods(@interface, typeResolver).ToList(); #else var interfaceMethods = IlReader.Methods(@interface, typeResolver); #endif var list = interfaceMethods.Select( interfaceMember => allPublic.Where(interfaceMember.IsMatchingInterfaceOverride).OrderByDescending(x => x.IsExplicitInterfaceImplementation).FirstOrDefault()) .Select(foundMethod => new LlvmWriter.Pair <IMethod, IMethod> { Key = foundMethod, Value = foundMethod }) .ToList(); ////Debug.Assert(list.All(i => i.Value != null), "Not all method could be resolved"); virtualTable.AddRange(list); }
private static IEnumerable <IType> IterateAllRequiredTypes(IType type, ReadingTypesContext readingTypesContext) { Debug.Assert(type != null, "Type is null"); if (type.BaseType != null) { DicoverGenericSpecializedTypesAndAdditionalTypes(type.BaseType, readingTypesContext); yield return(type.BaseType); } if (type.HasElementType) { DicoverGenericSpecializedTypesAndAdditionalTypes(type.GetElementType(), readingTypesContext); yield return(type.GetElementType()); } var interfaces = type.GetInterfaces(); if (interfaces != null) { foreach (var @interface in interfaces) { DicoverGenericSpecializedTypesAndAdditionalTypes(@interface, readingTypesContext); yield return(@interface); } } if (!type.IsInterface) { var fields = IlReader.Fields( type, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, _codeWriter); foreach (var field in fields) { ////#if DEBUG //// Debug.WriteLine("Processing field: {0}, Type: {1}", field.FullName, field.FieldType); ////#endif DicoverGenericSpecializedTypesAndAdditionalTypes(field.FieldType, readingTypesContext); if (field.FieldType.IsStructureType() && !field.FieldType.IsPointer) { yield return(field.FieldType); } } var ctors = IlReader.Constructors( type, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, _codeWriter); foreach (var requiredType in ctors.SelectMany(ctor => GetAllRequiredTypesForMethod(ctor, readingTypesContext))) { yield return(requiredType); } } var methods = IlReader.Methods( type, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance, _codeWriter); foreach (var requiredType in methods.SelectMany(method => GetAllRequiredTypesForMethod(method, readingTypesContext))) { yield return(requiredType); } }
/// <summary> /// </summary> /// <param name="type"> /// </param> /// <param name="typeResolver"> /// </param> public SynthesizedSingleDimArrayIListGetEnumeratorMethod(IType arrayType, ITypeResolver typeResolver) : base("GetEnumerator", arrayType, typeResolver.System.System_Collections_Generic_IEnumerator_T.Construct(arrayType.GetElementType())) { var codeList = new IlCodeBuilder(); codeList.LoadArgument(0); codeList.Add(Code.Newobj, 1); codeList.Add(Code.Newobj, 2); codeList.Add(Code.Ret); var locals = new List <IType>(); this._methodBody = new SynthesizedMethodBodyDecorator( null, locals, codeList.GetCode()); this._parameters = new List <IParameter>(); this._tokenResolutions = new List <object>(); var arraySegmentType = typeResolver.System.System_ArraySegment_T1.Construct(arrayType.GetElementType()); this._tokenResolutions.Add( IlReader.Constructors(arraySegmentType, typeResolver).First(c => c.GetParameters().Count() == 1)); this._tokenResolutions.Add( IlReader.Constructors(arraySegmentType.GetNestedTypes().First(), typeResolver).First(c => c.GetParameters().Count() == 1)); }
private static void ReadingTypes(IlReader ilReader, out List <IType> newListOfITypes, out SortedDictionary <string, IType> genDefinitionsByMetadataName, out SortedDictionary <IType, IEnumerable <IMethod> > genericMethodSpecializationsSorted) { // types in current assembly var genericTypeSpecializations = new HashSet <IType>(); var genericMethodSpecializations = new HashSet <IMethod>(); var types = ilReader.Types().Where(t => !t.IsGenericTypeDefinition).ToList(); var allTypes = ilReader.AllTypes().ToList(); #if !FOR_MSCORLIBTEST_DISABLE_RESORT newListOfITypes = ResortITypes(types, genericTypeSpecializations, genericMethodSpecializations); #else var newListOfITypes = allTypes; #endif // build quick access array for Generic Definitions genDefinitionsByMetadataName = new SortedDictionary <string, IType>(); foreach (var genDef in allTypes.Where(t => t.IsGenericTypeDefinition)) { genDefinitionsByMetadataName[genDef.MetadataFullName] = genDef; } DiscoverAllGenericVirtualMethods(allTypes, genericMethodSpecializations); DiscoverAllGenericMethodsOfInterfaces(allTypes, genericMethodSpecializations); genericMethodSpecializationsSorted = GroupGenericMethodsByType(genericMethodSpecializations); }
/// <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)) { } }
/// <summary> /// </summary> /// <param name="codeWriter"> /// </param> /// <param name="type"> /// </param> /// <param name="genericContext"> /// </param> public static void WriteTypeDefinition(ICodeWriter codeWriter, IType type, IGenericContext genericContext) { var fields = IlReader.Fields(type); var count = fields.Count(); var number = 1; Debug.Assert(!type.IsGenericType || !type.IsArray); codeWriter.WriteTypeStart(type, genericContext); codeWriter.WriteBeforeFields(count); if (!type.ToNormal().IsEnum) { foreach (var field in fields) { codeWriter.WriteFieldStart(field, number, count); codeWriter.WriteFieldEnd(field, number, count); number++; } } else { codeWriter.WriteFieldType(type.GetEnumUnderlyingType()); } codeWriter.WriteAfterFields(count); }
/// <summary> /// </summary> /// <param name="type"> /// </param> /// <param name="excludingStructs"> /// </param> /// <returns> /// </returns> public static IEnumerable <MemberLocationInfo> GetFieldsSizes(this IType type, bool excludingStructs = false) { foreach (var field in IlReader.Fields(type).Where(t => !t.IsStatic).ToList()) { var fieldSize = 0; var fieldType = field.FieldType; if (fieldType.IsClass || fieldType.IsArray || fieldType.IsPointer || fieldType.IsDelegate) { // pointer size yield return(new MemberLocationInfo(field, LlvmWriter.PointerSize)); } else if (!excludingStructs && fieldType.IsStructureType()) { yield return(new MemberLocationInfo(field, fieldType.GetTypeSize())); } else if (fieldType.Namespace == "System" && SystemTypeSizes.TryGetValue(fieldType.Name, out fieldSize)) { yield return(new MemberLocationInfo(field, fieldSize)); } else { foreach (var item in fieldType.GetTypeSizes()) { item.SetMainMember(field); yield return(item); } } } }
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"); }
public static IMethod GetMethodByName(this IType classType, string methodName, ITypeResolver typeResolver) { var normalType = classType.ToNormal(); var method = IlReader.Methods(normalType, typeResolver).FirstOrDefault(f => f.Name == methodName); Debug.Assert(method != null, string.Format("Method {0} could not be found", methodName)); return(method); }
public static IField GetFieldByName(this IType classType, string fieldName, ITypeResolver typeResolver) { var normalType = classType.ToNormal(); var field = IlReader.Fields(normalType, typeResolver).FirstOrDefault(f => f.Name == fieldName); Debug.Assert(field != null, string.Format("Field {0} could not be found", fieldName)); return(field); }
/// <summary> /// </summary> /// <param name="thisType"> /// </param> /// <returns> /// </returns> public static bool HasAnyVirtualMethodInCurrentType(this IType thisType) { if (IlReader.Methods(thisType).Any(m => m.IsVirtual || m.IsAbstract)) { return(true); } return(false); }
/// <summary> /// </summary> /// <param name="thisType"> /// </param> /// <returns> /// </returns> public static bool HasAnyVirtualMethodInCurrentType(this IType thisType, ITypeResolver typeResolver) { if (IlReader.Methods(thisType, typeResolver).Any(m => m.IsVirtual || m.IsOverride || m.IsAbstract)) { return(true); } return(false); }
/// <summary> /// </summary> /// <param name="virtualTable"> /// </param> /// <param name="thisType"> /// </param> /// <param name="llvmWriter"> /// </param> public static void BuildVirtualTable(this List <LlvmWriter.Pair <IMethod, IMethod> > virtualTable, IType thisType, LlvmWriter llvmWriter) { if (thisType.BaseType != null) { virtualTable.BuildVirtualTable(thisType.BaseType, llvmWriter); } // get all virtual methods in current type and replace or append foreach (var virtualOrAbstractMethod in IlReader.Methods(thisType).Where(m => m.IsVirtual || m.IsAbstract || m.IsOverride)) { if (virtualOrAbstractMethod.IsAbstract && virtualOrAbstractMethod.DeclaringType.Equals(thisType)) { virtualTable.Add(new LlvmWriter.Pair <IMethod, IMethod> { Key = virtualOrAbstractMethod, Value = virtualOrAbstractMethod }); continue; } // find method in virtual table var baseMethod = virtualOrAbstractMethod.IsOverride ? virtualTable.First(m => m.Key.IsMatchingOverride(virtualOrAbstractMethod)) : virtualTable.FirstOrDefault(m => m.Key.IsMatchingOverride(virtualOrAbstractMethod)); if (baseMethod == null) { virtualTable.Add(new LlvmWriter.Pair <IMethod, IMethod> { Key = virtualOrAbstractMethod, Value = virtualOrAbstractMethod }); continue; } baseMethod.Value = virtualOrAbstractMethod; } // append custom methods // custom GetHashCode for Enums if (thisType.ToNormal().IsEnum) { var getHashCodeMethod = new SynthesizedGetHashCodeMethod(thisType, llvmWriter); var baseMethod = virtualTable.First(m => m.Key.IsMatchingOverride(getHashCodeMethod)); baseMethod.Value = getHashCodeMethod; } // custom GetType // TODO: you need to append it before processing custom methods var getTypeMethod = new SynthesizedGetTypeMethod(thisType, llvmWriter); var baseGetTypeMethod = virtualTable.FirstOrDefault(m => m.Key.IsMatchingOverride(getTypeMethod)); #if !FOR_MSCORLIBTEST Debug.Assert(baseGetTypeMethod != null, "Could not find virtual method GetType (adjust source code and make GetType a virtual method"); #endif if (baseGetTypeMethod != null) { baseGetTypeMethod.Value = getTypeMethod; } }
/// <summary> /// </summary> /// <param name="ilReader"> /// </param> /// <param name="filter"> /// </param> /// <param name="codeWriter"> /// </param> private static void GenerateSource(IlReader ilReader, string[] filter, ICodeWriter codeWriter) { List <IType> newListOfITypes; SortedDictionary <string, IType> genDefinitionsByMetadataName; SortedDictionary <IType, IEnumerable <IMethod> > genericMethodSpecializationsSorted; ReadingTypes(ilReader, out newListOfITypes, out genDefinitionsByMetadataName, out genericMethodSpecializationsSorted); Writing(ilReader, filter, codeWriter, newListOfITypes, genDefinitionsByMetadataName, genericMethodSpecializationsSorted); }
/// <summary> /// </summary> /// <param name="source"> /// </param> /// <param name="outputFolder"> /// </param> /// <param name="args"> /// </param> public static void Convert(string source, string outputFolder, string[] args = null) { var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(source); var ilReader = new IlReader(source, args); ilReader.Load(); GenerateLlvm(ilReader, fileNameWithoutExtension, ilReader.SourceFilePath, ilReader.PdbFilePath, outputFolder, args); }
public static IMethod GetCtorMethodByParameters(IType stringType, IEnumerable <IParameter> getParameters, ITypeResolver typeResolver) { var parameters = getParameters.ToArray(); var method = IlReader.Methods(stringType, typeResolver) .FirstOrDefault(m => m.Name.StartsWith("Ctor") && m.GetParameters().ToArray().IsMatchingParams(parameters)); Debug.Assert(method != null, "String corresponding Ctor can't be found"); return(method); }
private CollectionMetadata DefineMembers(IType type, CollectionMetadata structureType) { var members = new CollectionMetadata(this.indexedMetadata); foreach (var field in IlReader.Fields(type, this.llvmWriter)) { members.Add(this.DefineMember(field, true, structureType)); } return(members); }
/// <summary> /// </summary> /// <param name="type"> /// </param> /// <param name="outputFolder"> /// </param> /// <param name="args"> /// </param> public static void Convert(Type type, string outputFolder, string[] args = null) { var name = type.Module.Name.Replace(".dll", string.Empty); var filePath = Path.GetDirectoryName(name); var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(name); var pdbFileName = Path.Combine(filePath, string.Concat(fileNameWithoutExtension, ".pdb")); var ilReader = new IlReader(); ilReader.Load(type); GenerateLlvm(ilReader, fileNameWithoutExtension, null, pdbFileName, outputFolder, args, new[] { type.FullName }); }
/// <summary> /// </summary> /// <param name="virtualTable"> /// </param> /// <param name="thisType"> /// </param> /// <param name="interface"> /// </param> public static void BuildVirtualInterfaceTable( this List <LlvmWriter.Pair <IMethod, IMethod> > virtualTable, IType thisType, IType @interface, ITypeResolver typeResolver) { var allPublic = IlReader.Methods( thisType, BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance, typeResolver); virtualTable.AddMethodsToVirtualInterfaceTable(@interface, allPublic, typeResolver); }
public static IField GetFieldByFieldNumber(this IType classType, int number, ITypeResolver typeResolver) { var normalType = classType.ToNormal(); var field = IlReader.Fields(normalType, typeResolver).Where(t => !t.IsStatic).Skip(number).FirstOrDefault(); Debug.Assert(field != null); if (field == null) { return(null); } return(field); }
/// <summary> /// </summary> /// <param name="type"> /// </param> /// <returns> /// </returns> public static int CalculateFieldsShift(this IType type, ITypeResolver typeResolver) { var fieldsShift = IlReader.Fields(type, typeResolver).Count(t => !t.IsStatic); if (type.BaseType != null) { fieldsShift += type.BaseType.GetFieldsShift(typeResolver); } fieldsShiftByType[type.FullName] = fieldsShift; return(fieldsShift); }
/// <summary> /// </summary> /// <param name="virtualTable"> /// </param> /// <param name="interface"> /// </param> private static void AddMethodsToVirtualInterfaceTableLayout(this List <IMethod> virtualTable, IType @interface, ITypeResolver typeResolver) { var allInterfaces = @interface.GetInterfaces(); var firstChildInterface = allInterfaces != null?allInterfaces.FirstOrDefault() : null; if (firstChildInterface != null) { // get all virtual methods in current type and replace or append virtualTable.AddMethodsToVirtualInterfaceTableLayout(firstChildInterface, typeResolver); } // get all virtual methods in current type and replace or append virtualTable.AddRange(IlReader.Methods(@interface, typeResolver)); }
//------------------------------------------------------------------------------ public static Constructor Create(ConstructorInfo aNative) { var ctor = new Constructor(); ctor.Name = aNative.Name; ctor._Instructions = IlReader.ReadInstructions(aNative); foreach (var param in aNative.GetParameters()) { ctor._Parameters.Add(Parameter.Create(param)); } return(ctor); }
//------------------------------------------------------------------------------ public static Method Create(MethodInfo aNative) { var method = new Method(); method.Name = aNative.Name; method._Instructions = IlReader.ReadInstructions(aNative); foreach (var param in aNative.GetParameters()) { method._Parameters.Add(Parameter.Create(param)); } return(method); }
/// <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>())) { } }
/// <summary> /// </summary> /// <param name="virtualTable"> /// </param> /// <param name="thisType"> /// </param> /// <param name="llvmWriter"> /// </param> public static void BuildVirtualTable( this List <LlvmWriter.Pair <IMethod, IMethod> > virtualTable, IType thisType, ITypeResolver typeResolver) { if (thisType.BaseType != null) { virtualTable.BuildVirtualTable(thisType.BaseType, typeResolver); } // get all virtual methods in current type and replace or append foreach ( var virtualOrAbstractMethod in IlReader.Methods(thisType, typeResolver).Where(m => m.IsVirtual || m.IsAbstract || m.IsOverride)) { Debug.Assert(!virtualOrAbstractMethod.IsGenericMethodDefinition); Debug.Assert(!virtualOrAbstractMethod.DeclaringType.IsGenericTypeDefinition); if (virtualOrAbstractMethod.IsAbstract && virtualOrAbstractMethod.DeclaringType.Equals(thisType)) { virtualTable.Add( new LlvmWriter.Pair <IMethod, IMethod> { Key = virtualOrAbstractMethod, Value = virtualOrAbstractMethod }); continue; } // find method in virtual table var baseMethod = virtualOrAbstractMethod.IsOverride ? virtualTable.First(m => m.Key.IsMatchingOverride(virtualOrAbstractMethod)) : virtualTable.FirstOrDefault(m => m.Key.IsMatchingOverride(virtualOrAbstractMethod)); if (baseMethod == null) { virtualTable.Add( new LlvmWriter.Pair <IMethod, IMethod> { Key = virtualOrAbstractMethod, Value = virtualOrAbstractMethod }); continue; } baseMethod.Value = virtualOrAbstractMethod; } }
public static void Register(ITypeResolver typeResolver) { // Registering UnsafeCastToStackPointerGen var tokenResolutions = new List <object>(); tokenResolutions.Add( IlReader.Constructors(typeResolver.System.System_IntPtr, typeResolver) .First( c => c.GetParameters().Count() == 1 && c.GetParameters().First().ParameterType.TypeEquals(typeResolver.System.System_Void.ToPointerType()))); var locals = new List <IType>(); // params will be taken from method MethodBodyBank.Register(Name, ByteCode, tokenResolutions, locals, null); }
/// <summary> /// </summary> /// <param name="classType"> /// </param> /// <param name="number"> /// </param> /// <returns> /// </returns> public static IType GetFieldTypeByFieldNumber(this IType classType, int number) { var normalType = classType.ToNormal(); if (normalType.IsEnum) { return(normalType.GetEnumUnderlyingType()); } var field = IlReader.Fields(normalType).Where(t => !t.IsStatic).Skip(number).FirstOrDefault(); if (field == null) { return(null); } return(field.FieldType); }