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)); }
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="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); } }
public static void GetLoadingArgumentsMethodBody( bool isVoid, ITypeResolver typeResolver, out object[] code, out IList <object> tokenResolutions, out IList <IType> locals, out IList <IParameter> parameters) { var stringType = typeResolver.System.System_String; var bytePointerType = typeResolver.System.System_SByte.ToPointerType(); parameters = new List <IParameter>(); parameters.Add(typeResolver.System.System_Int32.ToParameter()); parameters.Add(bytePointerType.ToPointerType().ToParameter()); var codeList = new List <object>(); codeList.AddRange( new object[] { Code.Ldarg_0, Code.Newarr, 1, 0, 0, 0, Code.Stloc_0, Code.Ldc_I4_0, Code.Stloc_1, Code.Br_S, 24, Code.Ldloc_0, Code.Ldloc_1, Code.Ldarg_1, Code.Dup, Code.Sizeof, 2, 0, 0, 0, Code.Add, Code.Starg_S, 1, Code.Ldind_I, Code.Newobj, 3, 0, 0, 0, Code.Stelem_Ref, Code.Ldloc_1, Code.Ldc_I4_1, Code.Add, Code.Stloc_1, Code.Ldloc_1, Code.Ldarg_0, Code.Blt_S, -28 }); code = codeList.ToArray(); locals = new List <IType>(); locals.Add(stringType.ToArrayType(1)); locals.Add(typeResolver.System.System_Int32); tokenResolutions = new List <object>(); tokenResolutions.Add(stringType); tokenResolutions.Add(bytePointerType); tokenResolutions.Add( IlReader.Constructors(stringType, typeResolver) .First( c => c.GetParameters().Count() == 1 && c.GetParameters().First().ParameterType.TypeEquals(bytePointerType))); }
/// <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); } }
public static void Register(ITypeResolver typeResolver) { var codeList = new IlCodeBuilder(); // get TypeCode of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 2); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.Add(Code.Conv_I4); // switch var @switch = codeList.Switch(); // goto default case //var defaultCaseLabel1 = codeList.Branch(Code.Br, Code.Br_S); // TODO: do not support Structs for now var defaultCaseLabel1 = codeList.CreateLabel(); codeList.Add(Code.Newobj, 20); codeList.Add(Code.Throw); // case 0(TypeCode.Empty) -> Default @switch.Labels.Add(defaultCaseLabel1); // case 1(TypeCode.Object) -> Default @switch.Labels.Add(defaultCaseLabel1); // case 2(TypeCode.DBNull) -> Default @switch.Labels.Add(defaultCaseLabel1); // case 3(TypeCode.Boolean) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 6); codeList.Add(Code.Stind_I1); codeList.Add(Code.Ret); // case 4(TypeCode.Char) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 7); codeList.Add(Code.Stind_I2); codeList.Add(Code.Ret); // case 5(TypeCode.SByte) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 8); codeList.Add(Code.Stind_I1); codeList.Add(Code.Ret); // case 6(TypeCode.Byte) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 9); codeList.Add(Code.Stind_I1); codeList.Add(Code.Ret); // case 7(TypeCode.Int16) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 10); codeList.Add(Code.Stind_I2); codeList.Add(Code.Ret); // case 8(TypeCode.UInt16) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 11); codeList.Add(Code.Stind_I2); codeList.Add(Code.Ret); // case 9(TypeCode.Int32) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 12); codeList.Add(Code.Stind_I4); codeList.Add(Code.Ret); // case 10(TypeCode.UInt32) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 13); codeList.Add(Code.Stind_I4); codeList.Add(Code.Ret); // case 11(TypeCode.Int64) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 14); codeList.Add(Code.Stind_I8); codeList.Add(Code.Ret); // case 12(TypeCode.UInt64) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 15); codeList.Add(Code.Stind_I8); codeList.Add(Code.Ret); // case 13(TypeCode.Single) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 16); codeList.Add(Code.Stind_R4); codeList.Add(Code.Ret); // case 14(TypeCode.Double) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 17); codeList.Add(Code.Stind_R8); codeList.Add(Code.Ret); // case 15(TypeCode.Decimal) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 18); codeList.Add(Code.Ret); // case 16(TypeCode.DateTime) @switch.Labels.Add(codeList.CreateLabel()); // get Value of TypedReference codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.LoadArgument(1); codeList.Add(Code.Unbox, 19); codeList.Add(Code.Ret); // case 17 -> Default @switch.Labels.Add(codeList.CreateLabel()); // throw NotSupportedException codeList.Add(Code.Newobj, 20); codeList.Add(Code.Throw); // case 18(TypeCode.String) -> Default @switch.Labels.Add(defaultCaseLabel1); // default: codeList.Add(defaultCaseLabel1); // get Value of TypedReference (default case) codeList.LoadArgument(0); codeList.Add(Code.Ldflda, 1); // IntPtr.m_value codeList.Add(Code.Ldfld, 3); codeList.Add(Code.Castclass, 4); codeList.LoadArgument(1); codeList.Add(Code.Stind_Ref); codeList.Add(Code.Ret); var typedReferenceType = typeResolver.System.System_TypedReference; var intPtrType = typeResolver.System.System_IntPtr; var tokenResolutions = new List <object>(); tokenResolutions.Add(typedReferenceType.GetFieldByName("Value", typeResolver)); tokenResolutions.Add(typedReferenceType.GetFieldByName("Type", typeResolver)); tokenResolutions.Add(intPtrType.GetFieldByName("m_value", typeResolver)); tokenResolutions.Add(typeResolver.System.System_Object.ToPointerType()); tokenResolutions.Add(typeResolver.System.System_Object); tokenResolutions.Add(typeResolver.System.System_Boolean); tokenResolutions.Add(typeResolver.System.System_Char); tokenResolutions.Add(typeResolver.System.System_SByte); tokenResolutions.Add(typeResolver.System.System_Byte); tokenResolutions.Add(typeResolver.System.System_Int16); tokenResolutions.Add(typeResolver.System.System_UInt16); tokenResolutions.Add(typeResolver.System.System_Int32); tokenResolutions.Add(typeResolver.System.System_UInt32); tokenResolutions.Add(typeResolver.System.System_Int64); tokenResolutions.Add(typeResolver.System.System_UInt64); tokenResolutions.Add(typeResolver.System.System_Single); tokenResolutions.Add(typeResolver.System.System_Double); tokenResolutions.Add(typeResolver.System.System_Decimal); tokenResolutions.Add(typeResolver.System.System_DateTime); tokenResolutions.Add( IlReader.Constructors(typeResolver.System.System_NotSupportedException, typeResolver).First(c => !c.GetParameters().Any())); var locals = new List <IType>(); var parameters = new List <IParameter>(); parameters.Add(typeResolver.System.System_Void.ToPointerType().ToParameter()); parameters.Add(typeResolver.System.System_Object.ToParameter()); MethodBodyBank.Register(Name, codeList.GetCode(), tokenResolutions, locals, parameters); }