private MethodDefinition InjectPropertySet(FieldDefinition field, string name, bool isPublic = true) { MethodAttributes methodAttributes = MethodAttributes.HideBySig | MethodAttributes.Virtual; if (isPublic) { methodAttributes = MethodAttributes.Public | methodAttributes; } else { methodAttributes = MethodAttributes.Private | methodAttributes; } var set = new MethodDefinition("set_" + name, methodAttributes, typeSystem.Void); var instructions = set.Body.Instructions; instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Ldarg_1)); instructions.Add(Instruction.Create(OpCodes.Stfld, field)); instructions.Add(Instruction.Create(OpCodes.Ret)); set.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, field.FieldType)); set.SemanticsAttributes = MethodSemanticsAttributes.Setter; set.CustomAttributes.Add(new CustomAttribute(msCoreReferenceFinder.CompilerGeneratedReference)); return(set); }
private MethodDefinition InjectPropertyGet(FieldDefinition field, string name, bool isPublic = true) { MethodAttributes methodAttributes = MethodAttributes.HideBySig | MethodAttributes.Virtual; if (isPublic) { methodAttributes = MethodAttributes.Public | methodAttributes; } else { methodAttributes = MethodAttributes.Private | methodAttributes; } var get = new MethodDefinition("get_" + name, methodAttributes, field.FieldType); var instructions = get.Body.Instructions; instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Ldfld, field)); instructions.Add(Instruction.Create(OpCodes.Stloc_0)); var inst = Instruction.Create(OpCodes.Ldloc_0); instructions.Add(Instruction.Create(OpCodes.Br_S, inst)); instructions.Add(inst); instructions.Add(Instruction.Create(OpCodes.Ret)); get.Body.Variables.Add(new VariableDefinition(field.FieldType)); get.Body.InitLocals = true; get.SemanticsAttributes = MethodSemanticsAttributes.Getter; get.CustomAttributes.Add(new CustomAttribute(msCoreReferenceFinder.CompilerGeneratedReference)); return(get); }
public MethodDefinition createMethod(String sMethodName, MethodAttributes maMethodAttributes, TypeReference trReturnType) { var newMethod = new MethodDefinition(sMethodName, maMethodAttributes, trReturnType); newMethod.Body.CilWorker.Emit(OpCodes.Ret); return newMethod; }
private void AddConstructor() { var baseCtor = this.module.Import(this.module.TypeSystem.Object.Resolve().GetConstructors().First()); const MethodAttributes methodAttributes = MethodAttributes.FamANDAssem | MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var ctor = new MethodDefinition( ".ctor", methodAttributes, this.module.TypeSystem.Void); foreach (var prop in this.properties) { prop.CtorParameter = new ParameterDefinition(prop.Name, ParameterAttributes.None, prop.GenericParameter); ctor.Parameters.Add(prop.CtorParameter); } var ctorBody = ctor.Body; ctorBody.MaxStackSize = 8; var ilproc = ctorBody.GetILProcessor(); ilproc.Emit(OpCodes.Ldarg_0); ilproc.Emit(OpCodes.Call, baseCtor); foreach (var prop in this.properties) { ilproc.Emit(OpCodes.Ldarg_0); ilproc.Emit(OpCodes.Ldarg, prop.CtorParameter); ilproc.Emit(OpCodes.Stfld, prop.FieldIlReference); } ilproc.Emit(OpCodes.Ret); this.definition.Methods.Add(ctor); }
static TypeDefinition TryGenerateExternalContainerType(TypeDefinition type, Context context, TypeReference objectReference, MethodReference preserveAttributeConstructor) { if (type.Module == context.Module || type.IsPublic) { return(null); } var externalTypeContainer = new TypeDefinition ( Context.kNamespace, Utility.GetSanitizedName(type.FullName, "_Container__"), TypeAttributes.Class | TypeAttributes.NotPublic, objectReference ); var baseEmptyConstructor = context.Module.ImportReference(objectReference.Resolve().GetConstructors().First()); const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var constructor = new MethodDefinition(".ctor", methodAttributes, context.ImportReference(typeof(void))); constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Call, baseEmptyConstructor)); constructor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); constructor.CustomAttributes.Add(new CustomAttribute(preserveAttributeConstructor)); externalTypeContainer.Methods.Add(constructor); var containerField = new FieldDefinition(ReflectedMemberPropertyName.ContainerFieldName, FieldAttributes.Public, objectReference); containerField.CustomAttributes.Add(new CustomAttribute(preserveAttributeConstructor)); externalTypeContainer.Fields.Add(containerField); context.Module.Types.Add(externalTypeContainer); return(externalTypeContainer); }
/// <summary> /// Injects the initializer. /// </summary> /// <param name="initializer">The initializer.</param> /// <exception cref="InjectionException">No module class found</exception> private void InjectInitializer(MethodReference initializer) { const MethodAttributes Attributes = MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; if (initializer == null) { throw new ArgumentNullException(nameof(initializer)); } var initializerReturnType = InjectionTargetAssembly.MainModule.Import(initializer.ReturnType); // Create a new method .cctor (a static constructor) inside the Assembly var cctor = new MethodDefinition(".cctor", Attributes, initializerReturnType); var il = cctor.Body.GetILProcessor(); il.Append(il.Create(OpCodes.Call, initializer)); il.Append(il.Create(OpCodes.Ret)); var moduleClass = InjectionTargetAssembly.MainModule.Types.FirstOrDefault(t => t.Name == "<Module>"); if (moduleClass == null) { throw new InjectionException("No module class found"); } moduleClass.Methods.Add(cctor); }
/// <summary> /// Adds a rewritable property to the <paramref name="typeDef">target type</paramref>. /// </summary> /// <param name="typeDef">The target type that will hold the newly-created property.</param> /// <param name="propertyName">The name of the property itself.</param> /// <param name="propertyType">The <see cref="TypeReference"/> instance that describes the property type.</param> public static void AddProperty(this TypeDefinition typeDef, string propertyName, TypeReference propertyType) { var fieldName = string.Format("__{0}_backingField", propertyName); var actualField = new FieldDefinition(fieldName, FieldAttributes.Private, propertyType); typeDef.Fields.Add(actualField); FieldReference backingField = actualField; if (typeDef.GenericParameters.Count > 0) { backingField = GetBackingField(fieldName, typeDef, propertyType); } var getterName = string.Format("get_{0}", propertyName); var setterName = string.Format("set_{0}", propertyName); const MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.Virtual; var module = typeDef.Module; var voidType = module.Import(typeof(void)); // Implement the getter and the setter var getter = AddPropertyGetter(propertyType, getterName, attributes, backingField); var setter = AddPropertySetter(propertyType, attributes, backingField, setterName, voidType); typeDef.AddProperty(propertyName, propertyType, getter, setter); }
public FluentMethodBuilder(ModuleDefinition module, string name) { _module = module; _name = name; _visibility = MethodAttributes.Public; _returnType = _module.Import(typeof(void)); }
public static void AddParameterlessConstructor(this TypeDefinition @this) { TypeReference baseType = @this.BaseType; Func <MethodDefinition, bool> findCtor = new Func <MethodDefinition, bool>(definition => definition.Name.Equals(".ctor") && definition.Parameters.Count == 0); bool isDefaultConstructorAlreadyDefined = @this.Methods.Any(findCtor); if (isDefaultConstructorAlreadyDefined) { return; } const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; MethodReference serializableContructor = baseType.ReferenceMethod(findCtor); if (serializableContructor == null) { return; } MethodDefinition serializationConstr = new MethodDefinition(".ctor", methodAttributes, @this.Module.TypeSystem.Void); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Call, @this.Module.ImportReference(serializableContructor))); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Nop)); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Nop)); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); @this.Methods.Add(serializationConstr); }
public static Func <MethodDefinition, bool> MethodAttributeSetter(Mono.Cecil.MethodAttributes attrs) { return(method => { method.Attributes = (method.Attributes & ~attrs) | attrs; return true; }); }
public MethodDefinition createMethod(String sMethodName, MethodAttributes maMethodAttributes, TypeReference trReturnType) { var newMethod = new MethodDefinition(sMethodName, maMethodAttributes, trReturnType); newMethod.Body.GetILProcessor().Emit(OpCodes.Ret); return(newMethod); }
private static void CreatePropertyInterface(this ModuleDefinition module, Type type, string namespaceName) { // public interface Int32Property // { // void Allocate(ref BlobBuilder builder, ref BlobVariable<Int32> blobVariable); // } // .class interface public abstract auto ansi // EntitiesBT.Editor.Int32Property // { // // .method public hidebysig virtual newslot abstract instance void // Allocate( // valuetype [Unity.Entities]Unity.Entities.BlobBuilder& builder, // valuetype [EntitiesBT.Runtime]EntitiesBT.Variable.BlobVariable`1<int32>& blobVariable // ) cil managed // { // // Can't find a body // } // end of method Int32Property::Allocate // } // end of class EntitiesBT.Editor.Int32Property const TypeAttributes interfaceAttributes = TypeAttributes.Class | TypeAttributes.Interface | TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.AutoClass | TypeAttributes.AnsiClass; var interfaceType = new TypeDefinition(namespaceName, $"{type.Name}Property", interfaceAttributes, module.TypeSystem.Object); const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Abstract; var allocateMethod = new MethodDefinition("Allocate", methodAttributes, module.TypeSystem.Void); var builderParameter = new ParameterDefinition( "builder" , ParameterAttributes.None , module.ImportReference(typeof(BlobBuilder)).MakeByReferenceType() ); var blobVariableParameter = new ParameterDefinition( "blobVariable" , ParameterAttributes.None , module.ImportReference(typeof(BlobVariable <>).MakeGenericType(type)).MakeByReferenceType() ); allocateMethod.Parameters.Add(builderParameter); allocateMethod.Parameters.Add(blobVariableParameter); interfaceType.Methods.Add(allocateMethod); module.Types.Add(interfaceType); foreach (var propertyType in _PROPERTY_TYPES.Value) { module.CreatePropertyClass(namespaceName, type, propertyType, new InterfaceImplementation(interfaceType)); } }
/// <summary> /// Create a module initializer in an assembly that contains a global::Module.Init() method. /// </summary> /// <param name="targetAssembly">The assembly to create the module initializer.</param> static void Main(FileInfo targetAssembly) { //https://www.coengoedegebure.com/module-initializers-in-dotnet/ Console.WriteLine($"Processing {targetAssembly}"); using (var symbolStream = GetSymbolInformation(targetAssembly.FullName, out ISymbolReaderProvider reader, out ISymbolWriterProvider writer)) { var module = ModuleDefinition.ReadModule(targetAssembly.FullName, new ReaderParameters { ReadSymbols = symbolStream != null || reader is EmbeddedPortablePdbReaderProvider, SymbolReaderProvider = reader, SymbolStream = symbolStream, InMemory = true, }); var type = module.GetType("Module"); if (type == null) { Console.WriteLine("Could not find global::Module class"); return; } var initMethod = type.GetMethods().FirstOrDefault(x => x.Name == "Init"); if (initMethod == null) { Console.WriteLine("Could not find Init() method on global::Module class"); return; } var assemblyModuleClass = module.GetType("<Module>"); if (assemblyModuleClass == null) { Console.WriteLine("Could not find <Module> class"); return; } const MethodAttributes Attributes = MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var cctor = new MethodDefinition(".cctor", Attributes, module.ImportReference(typeof(void))); var il = cctor.Body.GetILProcessor(); il.Append(il.Create(OpCodes.Call, initMethod)); il.Append(il.Create(OpCodes.Ret)); assemblyModuleClass.Methods.Add(cctor); module.Write(targetAssembly.FullName, new WriterParameters { WriteSymbols = writer != null, SymbolWriterProvider = writer, }); Console.WriteLine($"Wrote updated assembly '{targetAssembly.FullName}'"); } }
/// <summary> /// Adds the default constructor. For Binary Deserialization for a class that inherits from a types that implements /// ISerializable interface must override the constructor this signature: /// <code> /// protected Class ( SerializationInfo info, StreamingContext context ) //On the base class /// /// public CTOR(SerializationInfo info, StreamingContext context) : base(info,context) /// </code> /// </summary> /// <param name="this">The TypeDefinition.</param> public static void AddDefaultConstructor(this TypeDefinition @this) { TypeReference baseType = @this.BaseType; bool isDefaultConstructorToBeAdded = @this .BaseType .Resolve() .Interfaces .Any(reference => reference.InterfaceType.FullName == typeof(ISerializable).FullName); if (!isDefaultConstructorToBeAdded) return; if (@this.Module == null) return; Func<MethodDefinition, bool> findCtor = new Func<MethodDefinition, bool>(definition => definition.Name.Equals(".ctor") && definition.Parameters.Count == 2 && definition.Parameters.Any( par => par.Name.Equals("info") || par.Name.Equals("context"))); bool isDefaultConstructorAlreadyDefined = @this.Methods.Any(findCtor); if (isDefaultConstructorAlreadyDefined) return; const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; MethodReference serializableContructor = baseType.ReferenceMethod(findCtor); if (serializableContructor==null) return; TypeReference serializationInfo = @this.Module.Import(serializableContructor.Parameters[0].ParameterType); TypeReference streamingContext = @this.Module.Import(serializableContructor.Parameters[1].ParameterType); MethodDefinition serializationConstr = new MethodDefinition(".ctor", methodAttributes, @this.Module.TypeSystem.Void); ParameterDefinition par1 = new ParameterDefinition(serializableContructor.Parameters[0].Name, serializableContructor.Parameters[0].Attributes, serializationInfo); ParameterDefinition par2 = new ParameterDefinition(serializableContructor.Parameters[1].Name, serializableContructor.Parameters[1].Attributes, streamingContext); serializationConstr.Parameters.Add(par1); serializationConstr.Parameters.Add(par2); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_1)); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_2)); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Call, @this.Module.Import(serializableContructor))); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Nop)); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Nop)); serializationConstr.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); @this.Methods.Add(serializationConstr); }
protected MethodDefinition NewExplicitMethod(MethodInfo method) { MethodAttributes attributes = MethodAttributes.SpecialName | MethodAttributes.Private | MethodAttributes.Virtual; MethodDefinition definition = new MethodDefinition(method.DeclaringType.FullName + "." + method.Name, attributes, Import(method.ReturnType)); foreach (ParameterInfo pi in method.GetParameters()) { definition.Parameters.Add(new ParameterDefinition(pi.Name, Mono.Cecil.ParameterAttributes.None, Import(pi.ParameterType))); } definition.Overrides.Add(_context.Import(method)); return(definition); }
internal void AddOrReplaceIoc(ILProcessor il) { var mod = il.Body.Method.DeclaringType.Module; var myNamespace = mod.Types.Select(t => t.Namespace) .Where(n => !string.IsNullOrWhiteSpace(n)).OrderBy(n => n.Length).First(); const TAttr attr = TAttr.Class | TAttr.Public | TAttr.Sealed | TAttr.Abstract | TAttr.BeforeFieldInit; var objBase = mod.ImportReference(typeof(object)); var type = new TypeDefinition(myNamespace, IocName, attr, objBase); var oldType = mod.Types.FirstOrDefault(t => t.FullName == type.FullName); if (oldType != null) { mod.Types.Remove(oldType); } mod.Types.Add(type); var vesselRef = mod.ImportReference(typeof(IVessel)); const FAttr fieldAttr = FAttr.Static | FAttr.Private; var contField = new FieldDefinition(IocField, fieldAttr, vesselRef); type.Fields.Add(contField); const MAttr getAttrs = MAttr.Static | MAttr.Public | MAttr.SpecialName | MAttr.HideBySig; var getMethod = new MethodDefinition(IocMethod, getAttrs, vesselRef); type.Methods.Add(getMethod); ScopeMethod = getMethod; IocType = type; var gmil = getMethod.Body.GetILProcessor(); gmil.Append(gmil.Create(OpCodes.Ldsfld, contField)); gmil.Append(gmil.Create(OpCodes.Ret)); var voidRef = mod.ImportReference(typeof(void)); const MAttr constrAttrs = MAttr.Static | MAttr.SpecialName | MAttr.Private | MAttr.RTSpecialName | MAttr.HideBySig; var constr = new MethodDefinition(Defaults.StaticConstrName, constrAttrs, voidRef); type.Methods.Add(constr); var cil = constr.Body.GetILProcessor(); var multiMeth = typeof(DefaultVessel).GetConstructors().First(); var multiRef = mod.ImportReference(multiMeth); cil.Append(cil.Create(OpCodes.Newobj, multiRef)); cil.Append(cil.Create(OpCodes.Stsfld, contField)); cil.Append(cil.Create(OpCodes.Ret)); il.Append(il.Create(OpCodes.Call, getMethod)); il.Append(il.Create(OpCodes.Pop)); il.Append(il.Create(OpCodes.Ret)); }
/// <summary> /// Creates a property getter method implementation with the /// <paramref name="propertyType" /> as the return type. /// </summary> /// <param name="propertyType">Represents the <see cref="TypeReference">return type</see> for the getter method.</param> /// <param name="getterName">The getter method name.</param> /// <param name="attributes">The method attributes associated with the getter method.</param> /// <param name="backingField">The field that will store the instance that the getter method will retrieve.</param> /// <returns>A <see cref="MethodDefinition" /> representing the getter method itself.</returns> private static MethodDefinition AddPropertyGetter(TypeReference propertyType, string getterName, MethodAttributes attributes, FieldReference backingField) { var getter = new MethodDefinition(getterName, attributes, propertyType) { IsPublic = true, ImplAttributes = MethodImplAttributes.Managed | MethodImplAttributes.IL }; var IL = getter.Body.Instructions; IL.Add(Instruction.Create(OpCodes.Ldarg_0)); IL.Add(Instruction.Create(OpCodes.Ldfld, backingField)); IL.Add(Instruction.Create(OpCodes.Ret)); return(getter); }
/// <summary> /// Creates a property getter method implementation with the /// <paramref name="propertyType"/> as the return type. /// </summary> /// <param name="propertyType">Represents the <see cref="TypeReference">return type</see> for the getter method.</param> /// <param name="getterName">The getter method name.</param> /// <param name="attributes">The method attributes associated with the getter method.</param> /// <param name="backingField">The field that will store the instance that the getter method will retrieve.</param> /// <returns>A <see cref="MethodDefinition"/> representing the getter method itself.</returns> private static MethodDefinition AddPropertyGetter(TypeReference propertyType, string getterName, MethodAttributes attributes, FieldReference backingField) { var getter = new MethodDefinition(getterName, attributes, propertyType) { IsPublic = true, ImplAttributes = (MethodImplAttributes.Managed | MethodImplAttributes.IL) }; var IL = getter.GetILGenerator(); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, backingField); IL.Emit(OpCodes.Ret); return(getter); }
static string GetJavaAccess(MethodAttributes access) { switch (access) { case MethodAttributes.Public: return("public"); case MethodAttributes.FamORAssem: return("protected"); case MethodAttributes.Family: return("protected"); default: return("private"); } }
private static void CreatePropertyClass(this ModuleDefinition module, string namespaceName, Type valueType, Type propertyType, InterfaceImplementation @interface) { // .class public auto ansi beforefieldinit // EntitiesBT.Editor.Int32CustomViariableProperty // extends class [EntitiesBT.Runtime]EntitiesBT.Variable.CustomVariableProperty`1<int32> // implements EntitiesBT.Editor.Int32Property // { // // .method public hidebysig specialname rtspecialname instance void // .ctor() cil managed // { // .maxstack 8 // // IL_0000: ldarg.0 // this // IL_0001: call instance void class [EntitiesBT.Runtime]EntitiesBT.Variable.CustomVariableProperty`1<int32>::.ctor() // IL_0006: nop // IL_0007: ret // // } // end of method Int32CustomViariableProperty::.ctor // } // end of class EntitiesBT.Editor.Int32CustomViariableProperty const TypeAttributes classAttributes = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit; var baseType = propertyType.MakeGenericType(valueType); var classType = new TypeDefinition(namespaceName, $"{valueType.Name}{propertyType.Name}", classAttributes, module.ImportReference(baseType)); classType.Interfaces.Add(@interface); const MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var ctor = new MethodDefinition(".ctor", methodAttributes, module.TypeSystem.Void); var il = ctor.Body.GetILProcessor(); il.Append(il.Create(OpCodes.Ldarg_0)); // call the base constructor il.Append(il.Create(OpCodes.Call, module.ImportReference(baseType.GetConstructor(Array.Empty <Type>())))); il.Append(il.Create(OpCodes.Nop)); il.Append(il.Create(OpCodes.Ret)); var serializableAttribute = new CustomAttribute(module.ImportReference( typeof(SerializableAttribute).GetConstructor(Array.Empty <Type>()) )); classType.CustomAttributes.Add(serializableAttribute); classType.Methods.Add(ctor); module.Types.Add(classType); }
private void AddConstructor(TypeDefinition type, IDictionary <FieldReference, FieldDefinition> fields) { const MethodAttributes methodAttributes = MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Public; MethodDefinition ctor = new MethodDefinition(".ctor", methodAttributes, Import(typeof(void))); AddMethodParameters(ctor, fields.Values); ILProcessor cil = ctor.Body.GetILProcessor(); cil.Emit(OpCodes.Ldarg_0); cil.Emit(OpCodes.Call, DefaultObjectConstructor()); EmitFieldInitialization(ctor, fields.Values, ctor.Parameters); cil.Emit(OpCodes.Ret); type.Methods.Add(ctor); }
/// <summary> /// Adds a new method to the <paramref name="typeDef">target type</paramref>. /// </summary> /// <param name="typeDef">The type that will hold the newly-created method.</param> /// <param name="attributes">The <see cref="Mono.Cecil.MethodAttributes"/> parameter that describes the characteristics of the method.</param> /// <param name="methodName">The name to be given to the new method.</param> /// <param name="returnType">The method return type.</param> /// <param name="callingConvention">The calling convention of the method being created.</param> /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param> /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns> public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName, MethodAttributes attributes, MethodCallingConvention callingConvention, Type returnType, params Type[] parameterTypes) { var method = new MethodDefinition(methodName, attributes, null) { CallingConvention = callingConvention }; typeDef.Methods.Add(method); // Match the parameter types method.AddParameters(parameterTypes); // Match the return type method.SetReturnType(returnType); return(method); }
private void InjectInitializer(MethodReference callee) { Debug.Assert(Assembly != null); TypeReference voidRef = Assembly.MainModule.Import(callee.ReturnType); const MethodAttributes attributes = MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var cctor = new MethodDefinition(".cctor", attributes, voidRef); ILProcessor il = cctor.Body.GetILProcessor(); il.Append(il.Create(OpCodes.Call, callee)); il.Append(il.Create(OpCodes.Ret)); TypeDefinition moduleClass = Find(Assembly.MainModule.Types, t => t.Name == "<Module>"); moduleClass.Methods.Add(cctor); Debug.Assert(moduleClass != null, "Found no module class!"); }
/// <summary> /// Creates a module init for a C# assembly. /// </summary> /// <param name="method">The method to add to the module init.</param> private void CreateModuleInit(MethodDefinition method) { const MethodAttributes ModuleInitAttributes = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.Assembly | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var moduleType = assembly.MainModule.GetTypeResolved("<Module>"); // Get or create ModuleInit method var cctor = moduleType.Methods.FirstOrDefault(moduleTypeMethod => moduleTypeMethod.Name == ".cctor"); if (cctor == null) { cctor = new MethodDefinition(".cctor", ModuleInitAttributes, method.ReturnType); moduleType.Methods.Add(cctor); } bool isCallAlreadyDone = cctor.Body.Instructions.Any(instruction => instruction.OpCode == OpCodes.Call && instruction.Operand == method); // If the method is not called, we can add it if (!isCallAlreadyDone) { var ilProcessor = cctor.Body.GetILProcessor(); var retInstruction = cctor.Body.Instructions.FirstOrDefault(instruction => instruction.OpCode == OpCodes.Ret); var callMethod = ilProcessor.Create(OpCodes.Call, method); if (retInstruction == null) { // If a ret instruction is not present, add the method call and ret ilProcessor.Append(callMethod); ilProcessor.Emit(OpCodes.Ret); } else { // If a ret instruction is already present, just add the method to call before ilProcessor.InsertBefore(retInstruction, callMethod); } } }
public static void Inject(AssemblyDefinition lib) { const MethodAttributes Attributes = MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var initializer = getInititializer(lib); if (initializer == null) { throw new ArgumentNullException(nameof(initializer)); } var initializerReturnType = lib.MainModule.Import(initializer.ReturnType); // Create a new method .cctor (a static constructor) inside the Assembly var cctor = new MethodDefinition(".cctor", Attributes, initializerReturnType); var il = cctor.Body.GetILProcessor(); il.Append(il.Create(OpCodes.Call, initializer)); il.Append(il.Create(OpCodes.Ret)); var moduleClass = lib.MainModule.Types.FirstOrDefault(t => t.Name == "<Module>"); moduleClass.Methods.Add(cctor); }
/// <summary> /// Adds a new method to the <paramref name="typeDef">target type</paramref>. /// </summary> /// <param name="typeDef">The type that will hold the newly-created method.</param> /// <param name="attributes">The <see cref="Mono.Cecil.MethodAttributes"/> parameter that describes the characteristics of the method.</param> /// <param name="methodName">The name to be given to the new method.</param> /// <param name="returnType">The method return type.</param> /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param> /// <param name="genericParameterTypes">The list of generic argument types that will be used to define the method signature.</param> /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns> public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName, Mono.Cecil.MethodAttributes attributes, System.Type returnType, System.Type[] parameterTypes, System.Type[] genericParameterTypes) { var method = new MethodDefinition(methodName, attributes, typeDef.Module.Import(typeof(object))); typeDef.Methods.Add(method); //Match the generic parameter types foreach (var genericParameterType in genericParameterTypes) { method.AddGenericParameter(genericParameterType); } // Match the parameter types method.AddParameters(parameterTypes); // Match the return type method.SetReturnType(returnType); return(method); }
/// <summary> /// Adds a new method to the <paramref name="typeDef">target type</paramref>. /// </summary> /// <param name="typeDef">The type that will hold the newly-created method.</param> /// <param name="attributes">The <see cref="MethodAttributes"/> parameter that describes the characteristics of the method.</param> /// <param name="methodName">The name to be given to the new method.</param> /// <param name="returnType">The method return type.</param> /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param> /// <param name="genericParameterTypes">The list of generic argument types that will be used to define the method signature.</param> /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns> public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName, MethodAttributes attributes, Type returnType, Type[] parameterTypes, Type[] genericParameterTypes) { var method = new MethodDefinition(methodName, attributes, null); typeDef.Methods.Add(method); //Match the generic parameter types foreach (var genericParameterType in genericParameterTypes) { method.AddGenericParameter(genericParameterType); } // Match the parameter types method.AddParameters(parameterTypes); // Match the return type method.SetReturnType(returnType); return(method); }
public static DynamicMethodBody NewMethod (this TypeDefinition that, string methodName, MethodAttributes methodAttributes, Type returnType, AssemblyDefinition assembly) { var typeReference = assembly.MainModule.Import(returnType); var method = new MethodDefinition(methodName, methodAttributes, typeReference); ILProcessor worker = method.Body.GetILProcessor(); var emitter = new CecilILEmitter( assembly, worker, method.Body.Instructions.Add); var dinfo = new DynamicMethodInfo(emitter); method.LoadArgsTo(dinfo); that.Methods.Add(method); return(dinfo.Body); }
/// <summary> /// Adds a default constructor to the target type. /// </summary> /// <param name="parentType">The base class that contains the default constructor that will be used for constructor chaining..</param> /// <param name="targetType">The type that will contain the default constructor.</param> /// <returns>The default constructor.</returns> public static MethodDefinition AddDefaultConstructor(this TypeDefinition targetType, Type parentType) { ModuleDefinition module = targetType.Module; TypeReference voidType = module.Import(typeof(void)); MethodAttributes methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; ConstructorInfo objectConstructor = parentType.GetConstructor(flags, null, new Type[0], null); // Revert to the System.Object constructor // if the parent type does not have a default constructor if (objectConstructor == null) { objectConstructor = typeof(object).GetConstructor(new Type[0]); } MethodReference baseConstructor = module.Import(objectConstructor); // Define the default constructor var ctor = new MethodDefinition(".ctor", methodAttributes, voidType) { CallingConvention = MethodCallingConvention.StdCall, ImplAttributes = (MethodImplAttributes.IL | MethodImplAttributes.Managed) }; CilWorker IL = ctor.Body.CilWorker; // Call the constructor for System.Object, and exit IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Call, baseConstructor); IL.Emit(OpCodes.Ret); targetType.Constructors.Add(ctor); return(ctor); }
/// <summary> /// Creates a module init for a C# assembly. /// </summary> /// <param name="Method">The Method to add to the module init.</param> private void CreateModuleInit(MethodDefinition Method) { MethodAttributes ModuleInitAttributes = MethodAttributes.Static | MethodAttributes.Assembly | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; TypeDefinition ModuleType = Assembly.MainModule.GetType("<Module>"); // Get or create ModuleInit Method MethodDefinition Cctor = ModuleType.Methods.FirstOrDefault(X => X.Name == ".cctor"); if (Cctor == null) { Cctor = new MethodDefinition(".cctor", ModuleInitAttributes, Method.ReturnType); ModuleType.Methods.Add(Cctor); } Boolean IsCallAlreadyDone = Cctor.Body.Instructions.Any(X => X.OpCode == OpCodes.Call && X.Operand == Method); // If the Method is not called, we can add it if (IsCallAlreadyDone) return; ILProcessor IlProcessor = Cctor.Body.GetILProcessor(); var RetInstruction = Cctor.Body.Instructions.FirstOrDefault(X => X.OpCode == OpCodes.Ret); var CallMethod = IlProcessor.Create(OpCodes.Call, Method); if (RetInstruction == null) { // If a ret instruction is not present, add the Method call and ret IlProcessor.Append(CallMethod); IlProcessor.Emit(OpCodes.Ret); } else { // If a ret instruction is already present, just add the Method to call before IlProcessor.InsertBefore(RetInstruction, CallMethod); } }
public static GenericFuncContainer <MethodDefinition, bool> MethodNegAttributeComparer(Mono.Cecil.MethodAttributes negAttrs) { return(new GenericFuncContainer <MethodDefinition, bool>(method => { return (method.Attributes & negAttrs) == 0; })); }
/// <summary> /// Creates a property setter method implementation with the /// <paramref name="propertyType"/> as the setter parameter. /// </summary> /// <param name="propertyType">Represents the <see cref="TypeReference">parameter type</see> for the setter method.</param> /// <param name="attributes">The method attributes associated with the setter method.</param> /// <param name="backingField">The field that will store the instance for the setter method.</param> /// <param name="setterName">The method name of the setter method.</param> /// <param name="voidType">The <see cref="TypeReference"/> that represents <see cref="Void"/>.</param> /// <returns>A <see cref="MethodDefinition"/> that represents the setter method itself.</returns> private static MethodDefinition AddPropertySetter(TypeReference propertyType, MethodAttributes attributes, FieldReference backingField, string setterName, TypeReference voidType) { var setter = new MethodDefinition(setterName, attributes, voidType) { IsPublic = true, ImplAttributes = (MethodImplAttributes.Managed | MethodImplAttributes.IL) }; setter.Parameters.Add(new ParameterDefinition(propertyType)); var IL = setter.GetILGenerator(); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldarg_1); IL.Emit(OpCodes.Stfld, backingField); IL.Emit(OpCodes.Ret); return setter; }
/// <summary> /// Creates a property getter method implementation with the /// <paramref name="propertyType"/> as the return type. /// </summary> /// <param name="propertyType">Represents the <see cref="TypeReference">return type</see> for the getter method.</param> /// <param name="getterName">The getter method name.</param> /// <param name="attributes">The method attributes associated with the getter method.</param> /// <param name="backingField">The field that will store the instance that the getter method will retrieve.</param> /// <returns>A <see cref="MethodDefinition"/> representing the getter method itself.</returns> private static MethodDefinition AddPropertyGetter(TypeReference propertyType, string getterName, MethodAttributes attributes, FieldReference backingField) { var getter = new MethodDefinition(getterName, attributes, propertyType) { IsPublic = true, ImplAttributes = (MethodImplAttributes.Managed | MethodImplAttributes.IL) }; var IL = getter.GetILGenerator(); IL.Emit(OpCodes.Ldarg_0); IL.Emit(OpCodes.Ldfld, backingField); IL.Emit(OpCodes.Ret); return getter; }
/// <summary> /// Adds a new method to the <paramref name="typeDef">target type</paramref>. /// </summary> /// <param name="typeDef">The type that will hold the newly-created method.</param> /// <param name="attributes">The <see cref="MethodAttributes"/> parameter that describes the characteristics of the method.</param> /// <param name="methodName">The name to be given to the new method.</param> /// <param name="returnType">The method return type.</param> /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param> /// <param name="genericParameterTypes">The list of generic argument types that will be used to define the method signature.</param> /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns> public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName, MethodAttributes attributes, Type returnType, Type[] parameterTypes, Type[] genericParameterTypes) { var method = new MethodDefinition(methodName, attributes, null); typeDef.Methods.Add(method); //Match the generic parameter types foreach (var genericParameterType in genericParameterTypes) { method.AddGenericParameter(genericParameterType); } // Match the parameter types method.AddParameters(parameterTypes); // Match the return type method.SetReturnType(returnType); return method; }
/// <summary> /// Adds a new method to the <paramref name="typeDef">target type</paramref>. /// </summary> /// <param name="typeDef">The type that will hold the newly-created method.</param> /// <param name="attributes">The <see cref="Mono.Cecil.MethodAttributes"/> parameter that describes the characteristics of the method.</param> /// <param name="methodName">The name to be given to the new method.</param> /// <param name="returnType">The method return type.</param> /// <param name="callingConvention">The calling convention of the method being created.</param> /// <param name="parameterTypes">The list of argument types that will be used to define the method signature.</param> /// <returns>A <see cref="MethodDefinition"/> instance that represents the newly-created method.</returns> public static MethodDefinition DefineMethod(this TypeDefinition typeDef, string methodName, MethodAttributes attributes, MethodCallingConvention callingConvention, Type returnType, params Type[] parameterTypes) { var method = new MethodDefinition(methodName, attributes, null) { CallingConvention = callingConvention }; typeDef.Methods.Add(method); // Match the parameter types method.AddParameters(parameterTypes); // Match the return type method.SetReturnType(returnType); return method; }
private TypeDefinition CreateRepositoryType(TypeDefinition repoTypeDef, TypeCodeGenInfo rti, MethodAttributes methodAttributes, string repoTypeNameFormat, TypeAttributes typeAttributes, bool isImplementation, IEnumerable<TypeReference> interfacesToImplement = null) { var tt = (ResourceType)rti.TransformedType; repoTypeDef.Namespace = this.assemblyName; repoTypeDef.Name = string.Format(repoTypeNameFormat, rti.TransformedType.Name); repoTypeDef.Attributes = typeAttributes; if (isImplementation) repoTypeDef.BaseType = rti.CustomRepositoryBaseTypeReference; repoTypeDef.Interfaces.AddRange(interfacesToImplement ?? Enumerable.Empty<TypeReference>()); var baseTypeGenericDef = rti.CustomRepositoryBaseTypeDefinition; var baseTypeGenericArgs = rti.CustomRepositoryBaseTypeReference.GenericArguments.ToArray(); foreach (var subType in tt.MergedTypes.Concat(tt)) { if (subType.PostAllowed) { AddRepositoryFormPostMethod(methodAttributes, isImplementation, subType, repoTypeDef, baseTypeGenericDef, baseTypeGenericArgs); } } if (tt.PrimaryId != null) { AddRepositoryGetByIdMethod(rti, methodAttributes, isImplementation, tt, repoTypeDef, baseTypeGenericDef, baseTypeGenericArgs, "Get"); AddRepositoryGetByIdMethod(rti, methodAttributes, isImplementation, tt, repoTypeDef, baseTypeGenericDef, baseTypeGenericArgs, "GetLazy"); } // Constructor if (isImplementation) { var baseCtor = baseTypeGenericDef.GetConstructors().First(); var baseCtorRef = Import(baseCtor).MakeHostInstanceGeneric(baseTypeGenericArgs); var ctor = new MethodDefinition( ".ctor", MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Public, VoidTypeRef); baseCtor.Parameters.Select(x => new ParameterDefinition(x.Name, x.Attributes, Import(x.ParameterType))) .AddTo(ctor.Parameters); ctor.Body.MaxStackSize = 8; var ctorIlProcessor = ctor.Body.GetILProcessor(); ctorIlProcessor.Append(Instruction.Create(OpCodes.Ldarg_0)); foreach (var ctorParam in ctor.Parameters) ctorIlProcessor.Append(Instruction.Create(OpCodes.Ldarg, ctorParam)); ctorIlProcessor.Append(Instruction.Create(OpCodes.Call, baseCtorRef)); ctorIlProcessor.Append(Instruction.Create(OpCodes.Ret)); repoTypeDef.Methods.Add(ctor); } if (!this.module.Types.Contains(repoTypeDef)) this.module.Types.Add(repoTypeDef); return repoTypeDef; }
private void AddRepositoryGetByIdMethod(TypeCodeGenInfo rti, MethodAttributes methodAttributes, bool isImplementation, TransformedType tt, TypeDefinition repoTypeDef, TypeDefinition baseTypeGenericDef, TypeReference[] baseTypeGenericArgs, string methodName) { var method = new MethodDefinition(methodName, methodAttributes, rti.InterfaceType); var idType = tt.PrimaryId.PropertyType; if (!(idType is TypeSpec)) throw new NotSupportedException("Id needs to be a shared type."); var idTypeRef = Import(idType.Type); method.Parameters.Add(new ParameterDefinition(tt.PrimaryId.LowerCaseName, 0, idTypeRef)); repoTypeDef.Methods.Add(method); if (isImplementation) { var baseGetMethodRef = Import(Import(typeof(ClientRepository<,>)).Resolve().Methods.First(x => x.Name == methodName)) .MakeHostInstanceGeneric(baseTypeGenericArgs); var ilproc = method.Body.GetILProcessor(); ilproc.Emit(OpCodes.Ldarg_0); ilproc.Emit(OpCodes.Ldarg_1); if (idType.Type.IsValueType) ilproc.Emit(OpCodes.Box, idTypeRef); else ilproc.Emit(OpCodes.Castclass, idTypeRef); ilproc.Emit(OpCodes.Callvirt, baseGetMethodRef); ilproc.Emit(OpCodes.Ret); } }
private void AddRepositoryFormPostMethod(MethodAttributes methodAttributes, bool isImplementation, ResourceType subType, TypeDefinition repoTypeDef, TypeDefinition baseTypeGenericDef, TypeReference[] baseTypeGenericArgs) { var postReturnTypeRef = this.clientTypeInfoDict[subType.PostReturnType].InterfaceType; var method = new MethodDefinition("Post", methodAttributes, postReturnTypeRef); method.Parameters.Add(new ParameterDefinition("form", 0, this.clientTypeInfoDict[subType].PostFormType)); repoTypeDef.Methods.Add(method); if (isImplementation) { var basePostMethodRef = Import( Import(typeof(ClientRepository<,>)).Resolve().GetMethods() .Single( x => x.Name == "Post" && x.Parameters.Count == 1 && x.Parameters[0].Name == "form") ).MakeHostInstanceGeneric(baseTypeGenericArgs); var ilproc = method.Body.GetILProcessor(); ilproc.Emit(OpCodes.Ldarg_0); ilproc.Emit(OpCodes.Ldarg_1); ilproc.Emit(OpCodes.Callvirt, basePostMethodRef); ilproc.Emit(OpCodes.Castclass, postReturnTypeRef); ilproc.Emit(OpCodes.Ret); } }
public static DynamicMethodBody NewMethod (this TypeDefinition that, string methodName, MethodAttributes methodAttributes, Type returnType, AssemblyDefinition assembly) { var typeReference = assembly.MainModule.Import(returnType); var method = new MethodDefinition(methodName, methodAttributes, typeReference); ILProcessor worker = method.Body.GetILProcessor(); var emitter = new CecilILEmitter( assembly, worker, method.Body.Instructions.Add); var dinfo = new DynamicMethodInfo(emitter); method.LoadArgsTo(dinfo); that.Methods.Add(method); return dinfo.Body; }