public PropertyEmitter(TypeBuilder owner, string name, Type propertyType, FieldBuilder propertyChangedField) { this.owner = owner; this.propertyChangedField = propertyChangedField; fieldBuilder = owner.DefineField(String.Format("<{0}>", name), propertyType, FieldAttributes.Private); getterBuilder = owner.DefineMethod(String.Format("get_{0}", name), MethodAttributes.Public|MethodAttributes.Virtual|MethodAttributes.HideBySig|MethodAttributes.SpecialName, propertyType, Type.EmptyTypes); ILGenerator getterIl = getterBuilder.GetILGenerator(); getterIl.Emit(OpCodes.Ldarg_0); getterIl.Emit(OpCodes.Ldfld, fieldBuilder); getterIl.Emit(OpCodes.Ret); setterBuilder = owner.DefineMethod(String.Format("set_{0}", name), MethodAttributes.Public|MethodAttributes.Virtual|MethodAttributes.HideBySig|MethodAttributes.SpecialName, typeof(void), new[] {propertyType}); ILGenerator setterIl = setterBuilder.GetILGenerator(); setterIl.Emit(OpCodes.Ldarg_0); setterIl.Emit(OpCodes.Ldarg_1); setterIl.Emit(OpCodes.Stfld, fieldBuilder); if (propertyChangedField != null) { setterIl.Emit(OpCodes.Ldarg_0); setterIl.Emit(OpCodes.Dup); setterIl.Emit(OpCodes.Ldfld, propertyChangedField); setterIl.Emit(OpCodes.Ldstr, name); setterIl.Emit(OpCodes.Call, proxyBase_NotifyPropertyChanged); } setterIl.Emit(OpCodes.Ret); propertyBuilder = owner.DefineProperty(name, PropertyAttributes.None, propertyType, null); propertyBuilder.SetGetMethod(getterBuilder); propertyBuilder.SetSetMethod(setterBuilder); }
internal static MethodBuilder GetterMethodFor(TypeBuilder typeBuilder, PropertyBuilder property, MethodAttributes access) { var getterMethod = typeBuilder.DefineMethod("get_" + property.Name, access, property.PropertyType, null); property.SetGetMethod(getterMethod); return getterMethod; }
private void BuildGetter(TypeBuilder typeBuilder, PropertyInfo contractProperty, PropertyBuilder builder) { var getMethod = contractProperty.GetGetMethod(); if(null != getMethod) { var getMethodBuilder = new ProxyMethodImplementationStrategy().BuildMethodProxy(typeBuilder, getMethod); builder.SetGetMethod(getMethodBuilder); } }
private void AddGetter(System.Reflection.Emit.TypeBuilder typeBuilder, FieldBuilder fieldBuilder, PropertyBuilder propertyBuilder) { MethodBuilder propertyGetter = typeBuilder.DefineMethod("get_" + _propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, _propertyType, Type.EmptyTypes); var ilGenerator = propertyGetter.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, fieldBuilder); ilGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(propertyGetter); }
/// <summary> /// Creates the get method. /// </summary> /// <param name="typeBuilder">The type builder.</param> /// <param name="prop">The prop.</param> /// <param name="fieldBuilder">The field builder.</param> /// <param name="propBuilder">The prop builder.</param> private static void CreateGetMethod(TypeBuilder typeBuilder, PropertyInfo prop, FieldInfo fieldBuilder, PropertyBuilder propBuilder) { var getMethodBuilder = typeBuilder.DefineMethod( "get_" + prop.Name, GetSetAttributes, prop.PropertyType, Type.EmptyTypes); var getIl = getMethodBuilder.GetILGenerator(); getIl.Emit(OpCodes.Ldarg_0); getIl.Emit(OpCodes.Ldfld, fieldBuilder); getIl.Emit(OpCodes.Ret); propBuilder.SetGetMethod(getMethodBuilder); }
private void AddGetter(System.Reflection.Emit.TypeBuilder typeBuilder, PropertyBuilder propertyBuilder) { MethodBuilder propertyGetter = typeBuilder.DefineMethod("get_" + _propertyInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, _propertyInfo.PropertyType, Type.EmptyTypes); var ilGenerator = propertyGetter.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, _aggregate); MethodInfo getter = _propertyInfo.GetAccessors().First(accessor => accessor.ReturnType != typeof (void)); ilGenerator.Emit(OpCodes.Callvirt, getter); ilGenerator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(propertyGetter); }
private static void CreateGetter(TypeBuilder typeBuilder, PropertyBuilder propertyBuilder, DataColumn column) { var getMethodBuilder = typeBuilder.DefineMethod( "get_" + column.ColumnName, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, column.DataType, Type.EmptyTypes); var getMethodIL = getMethodBuilder.GetILGenerator(); getMethodIL.Emit(OpCodes.Ldarg_0); getMethodIL.Emit(OpCodes.Ldstr, column.ColumnName); getMethodIL.Emit(OpCodes.Callvirt, GetValueMethod.MakeGenericMethod(column.DataType)); getMethodIL.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getMethodBuilder); }
public static Type BuildPropertyObject(System.Collections.Generic.IEnumerable <System.Collections.Generic.KeyValuePair <string, Type> > obj) { string nameOfDLL = "magic.dll"; string nameOfAssembly = "magic_Assembly"; string nameOfModule = "magic_Module"; string nameOfType = "magic_Type"; System.Reflection.AssemblyName assemblyName = new System.Reflection.AssemblyName { Name = nameOfAssembly }; System.Reflection.Emit.AssemblyBuilder assemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assemblyName, System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave); System.Reflection.Emit.ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(nameOfModule, nameOfDLL); System.Reflection.Emit.TypeBuilder typeBuilder = moduleBuilder.DefineType(nameOfType, System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class); foreach (var prop in obj) { string Name = prop.Key; Type DataType = prop.Value; System.Reflection.Emit.FieldBuilder field = typeBuilder.DefineField("_" + Name, DataType, System.Reflection.FieldAttributes.Private); System.Reflection.Emit.PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(Name, System.Reflection.PropertyAttributes.SpecialName, DataType, null); System.Reflection.MethodAttributes methodAttributes = System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.SpecialName; System.Reflection.Emit.MethodBuilder methodBuilderGetter = typeBuilder.DefineMethod("get_" + Name, methodAttributes, DataType, new Type[] { }); System.Reflection.Emit.MethodBuilder methodBuilderSetter = typeBuilder.DefineMethod("set_" + Name, methodAttributes, typeof(void), new Type[] { DataType }); System.Reflection.Emit.ILGenerator ilGeneratorGetter = methodBuilderGetter.GetILGenerator(); ilGeneratorGetter.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilGeneratorGetter.Emit(System.Reflection.Emit.OpCodes.Ldfld, field); ilGeneratorGetter.Emit(System.Reflection.Emit.OpCodes.Ret); System.Reflection.Emit.ILGenerator ilGeneratorSetter = methodBuilderSetter.GetILGenerator(); ilGeneratorSetter.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilGeneratorSetter.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); ilGeneratorSetter.Emit(System.Reflection.Emit.OpCodes.Stfld, field); ilGeneratorSetter.Emit(System.Reflection.Emit.OpCodes.Ret); propertyBuilder.SetGetMethod(methodBuilderGetter); propertyBuilder.SetSetMethod(methodBuilderSetter); } // Yes! you must do this, it should not be needed but it is! Type dynamicType = typeBuilder.CreateType(); // Save to file assemblyBuilder.Save(nameOfDLL); return(dynamicType); }
public static Type BuildDynamicTypeWithProperties(string classname, Dictionary <string, Type> properties) { AppDomain myDomain = Thread.GetDomain(); AssemblyName myAsmName = Assembly.GetExecutingAssembly().GetName(); AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndCollect); ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(myAsmName.Name); MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; TypeBuilder typebuilder = myModBuilder.DefineType(classname, TypeAttributes.Public); foreach (var propertie in properties) { FieldBuilder fieldbuilder = typebuilder.DefineField(propertie.Key.ToLower(), propertie.Value, FieldAttributes.Private); System.Reflection.Emit.PropertyBuilder getsetbuilder = typebuilder.DefineProperty(propertie.Key, PropertyAttributes.HasDefault, propertie.Value, null); //Define the "get" accessor method MethodBuilder getmethodbuilder = typebuilder.DefineMethod(string.Format("get_{0}", propertie.Key), getSetAttr, propertie.Value, Type.EmptyTypes); ILGenerator getil = getmethodbuilder.GetILGenerator(); getil.Emit(OpCodes.Ldarg_0); getil.Emit(OpCodes.Ldfld, fieldbuilder); getil.Emit(OpCodes.Ret); //Define the "set" accessor method MethodBuilder setmethodbuilder = typebuilder.DefineMethod(string.Format("set_{0}", propertie.Key), getSetAttr, null, new Type[] { propertie.Value }); ILGenerator setil = setmethodbuilder.GetILGenerator(); setil.Emit(OpCodes.Ldarg_0); setil.Emit(OpCodes.Ldarg_1); setil.Emit(OpCodes.Stfld, fieldbuilder); setil.Emit(OpCodes.Ret); //Add get/set getsetbuilder.SetGetMethod(getmethodbuilder); getsetbuilder.SetSetMethod(setmethodbuilder); } return(typebuilder.CreateType()); }
private static void SetAccessors(PropertyBuilder property, IEnumerable<RppMethodInfo> methods) { string propertyName = property.Name; foreach (RppMethodInfo method in methods) { if (method.Name == RppMethodInfo.GetGetterAccessorName(propertyName)) { property.SetGetMethod((MethodBuilder) method.Native); } else if (method.Name == RppMethodInfo.GetSetterAccessorName(propertyName)) { property.SetSetMethod((MethodBuilder) method.Native); } } }
unsafe void GenerateProxyMethod(MethodDescriptor desc) { if (!desc.IsVisible()) { Console.WriteLine("HIDDEN: {0}", desc); return; } MethodAttributes methodAttrs = MethodAttributes.Public | MethodAttributes.Virtual; String methodName = desc.name; if (desc.IsGetter()) { methodName = "get_" + desc.name; methodAttrs |= MethodAttributes.SpecialName; } else if (desc.IsSetter()) { methodName = "set_" + desc.name; methodAttrs |= MethodAttributes.SpecialName; } // Fix up interface types in parameters Type ret = desc.resultType; if (ret == typeof(object)) ret = FixupInterfaceType(desc.args[desc.args.Length - 1]); Type[] argTypes = (Type[])desc.argTypes.Clone(); for (int i = 0; i < argTypes.Length; i++) { if (argTypes[i] == typeof(object)) argTypes[i] = FixupInterfaceType(desc.args[i]); } MethodBuilder meth = tb.DefineMethod(methodName, methodAttrs, ret, argTypes); ilg = meth.GetILGenerator(); bufLocal = ilg.DeclareLocal(System.Type.GetType("System.Int32*")); LocalBuilder guidLocal = ilg.DeclareLocal(typeof(System.Guid)); TypeInfo.ParamDescriptor[] args = desc.args; Type marshalType = typeof(System.Runtime.InteropServices.Marshal); // Marshal.AllocCoTaskMem(constify(argBufSize)) int argCount = args.Length; int argBufSize = VARIANT_SIZE * args.Length; ilg.Emit(OpCodes.Ldc_I4, argBufSize); ilg.Emit(OpCodes.Call, marshalType.GetMethod("AllocCoTaskMem")); ilg.Emit(OpCodes.Stloc, bufLocal); for (int i = 0; i < argCount; i++) { TypeInfo.ParamDescriptor param = args[i]; TypeInfo.TypeDescriptor type = param.type; IntPtr ptr = IntPtr.Zero; sbyte flags = 0; EmitTypeStore(type, i); if (param.IsOut()) { EmitOutParamPrep(type, i); if (!param.IsIn()) continue; } switch (type.tag) { case TypeTag.Int8: case TypeTag.Int16: case TypeTag.UInt8: case TypeTag.UInt16: case TypeTag.Char: case TypeTag.WChar: case TypeTag.UInt32: EmitPrepareArgStore(i); // XXX do I need to cast this? ilg.Emit(OpCodes.Castclass, typeof(Int32)); ilg.Emit(OpCodes.Stind_I4); break; case TypeTag.Int32: EmitPrepareArgStore(i); ilg.Emit(OpCodes.Stind_I4); break; case TypeTag.NSIdPtr: EmitPrepareArgStore(i); ilg.Emit(OpCodes.Stind_I4); // XXX 64-bitness break; case TypeTag.String: EmitPrepareArgStore(i); // the string arg is now on the stack ilg.Emit(OpCodes.Call, marshalType.GetMethod("StringToCoTaskMemAnsi")); ilg.Emit(OpCodes.Stind_I4); break; case TypeTag.Interface: EmitPrepareArgStore(i); // MRP is the object passed as this arg ilg.Emit(OpCodes.Ldloca_S, guidLocal); ilg.Emit(OpCodes.Ldstr, param.GetIID().ToString()); ilg.Emit(OpCodes.Call, guidCtor); ilg.Emit(OpCodes.Ldloca_S, guidLocal); // stack is now objarg, ref guid ilg.Emit(OpCodes.Call, typeof(CLRWrapper).GetMethod("Wrap")); // now stack has the IntPtr in position to be stored. ilg.Emit(OpCodes.Stind_I4); break; default: /* String msg = String.Format("{0}: type {1} not supported", param.Name(), type.tag.ToString()); throw new Exception(msg); */ break; } EmitPtrAndFlagsStore(i, ptr, flags); } //= (void)XPTC_InvokeByIndex(thisptr, desc.index, length, bufLocal); ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldfld, thisField); ilg.Emit(OpCodes.Ldc_I4, desc.index); ilg.Emit(OpCodes.Ldc_I4, args.Length); ilg.Emit(OpCodes.Ldloc_0); ilg.Emit(OpCodes.Call, typeof(Mozilla.XPCOM.Invoker). GetMethod("XPTC_InvokeByIndex", BindingFlags.Static | BindingFlags.NonPublic)); ilg.Emit(OpCodes.Pop); if (ret == typeof(string)) { ilg.Emit(OpCodes.Ldstr, "FAKE RETURN STRING"); } else if (ret == typeof(object)) { ilg.Emit(OpCodes.Newobj, typeof(object).GetConstructor(new Type[0])); } else if (ret == typeof(int)) { EmitLoadReturnSlot_1(args.Length); } else if (ret == typeof(void)) { // Nothing } else { throw new Exception(String.Format("return type {0} not " + "supported yet", desc.result.type.tag)); } //= Marshal.FreeCoTaskMem(bufLocal); ilg.Emit(OpCodes.Ldloc, bufLocal); ilg.Emit(OpCodes.Call, marshalType.GetMethod("FreeCoTaskMem")); ilg.Emit(OpCodes.Ret); ilg = null; bufLocal = null; if (desc.IsSetter()) { if (lastProperty != null && lastProperty.Name == desc.name) { lastProperty.SetSetMethod(meth); } else { tb.DefineProperty(desc.name, PROPERTY_ATTRS, desc.resultType, new Type[0]).SetSetMethod(meth); } lastProperty = null; } else if (desc.IsGetter()) { lastProperty = tb.DefineProperty(desc.name, PROPERTY_ATTRS, desc.resultType, new Type[0]); lastProperty.SetGetMethod(meth); } else { lastProperty = null; } }
private static void EmitBaseGetter(TypeBuilder typeBuilder, PropertyBuilder propertyBuilder, PropertyInfo baseProperty) { if (CanProxyGetter(baseProperty)) { var baseGetter = baseProperty.GetGetMethod(true); const MethodAttributes getterAttributes = MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual; var getterAccess = baseGetter.Attributes & MethodAttributes.MemberAccessMask; // Define a property getter override in the proxy type var getterBuilder = typeBuilder.DefineMethod( "get_" + baseProperty.Name, getterAccess | getterAttributes, baseProperty.PropertyType, Type.EmptyTypes); var gen = getterBuilder.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Call, baseGetter); gen.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getterBuilder); } }
void GenerateInterfaceMethod(TypeInfo.MethodDescriptor desc) { if (desc == null || !desc.IsVisible()) return; MethodAttributes methodAttrs = METHOD_ATTRS; String methodName = desc.name; if (desc.IsGetter()) { methodName = "get_" + desc.name; methodAttrs |= MethodAttributes.SpecialName; } else if (desc.IsSetter()) { methodName = "set_" + desc.name; methodAttrs |= MethodAttributes.SpecialName; } // Fix up interface types in parameters Type ret = desc.resultType; if (ret == typeof(object)) ret = FixupInterfaceType(desc.args[desc.args.Length - 1]); Type[] argTypes = (Type[])desc.argTypes.Clone(); for (int i = 0; i < argTypes.Length; i++) { if (argTypes[i] == typeof(object)) argTypes[i] = FixupInterfaceType(desc.args[i]); } MethodBuilder meth = tb.DefineMethod(methodName, methodAttrs, ret, desc.argTypes); if (desc.IsSetter()) { if (lastProperty != null && lastProperty.Name == desc.name) { lastProperty.SetSetMethod(meth); } else { tb.DefineProperty(desc.name, PROPERTY_ATTRS, desc.resultType, new Type[0]).SetSetMethod(meth); } lastProperty = null; } else if (desc.IsGetter()) { lastProperty = tb.DefineProperty(desc.name, PROPERTY_ATTRS, desc.resultType, new Type[0]); lastProperty.SetGetMethod(meth); } else { lastProperty = null; } }
protected void DefineBuilders(MemberKind kind, ParametersCompiled parameters) { // FIXME - PropertyAttributes.HasDefault ? PropertyBuilder = Parent.TypeBuilder.DefineProperty ( GetFullName (MemberName), PropertyAttributes.None, MemberType.GetMetaInfo (), parameters.GetMetaInfo ()); PropertySpec spec; if (kind == MemberKind.Indexer) spec = new IndexerSpec (Parent.Definition, this, MemberType, parameters, PropertyBuilder, ModFlags); else spec = new PropertySpec (kind, Parent.Definition, this, MemberType, PropertyBuilder, ModFlags); spec.Get = Get.Spec; spec.Set = Set.Spec; if (!Get.IsDummy) { PropertyBuilder.SetGetMethod (GetBuilder); } if (!Set.IsDummy) { PropertyBuilder.SetSetMethod (SetBuilder); } Parent.MemberCache.AddMember (this, Get.IsDummy ? Get.Name : GetBuilder.Name, Get.Spec); Parent.MemberCache.AddMember (this, Set.IsDummy ? Set.Name : SetBuilder.Name, Set.Spec); Parent.MemberCache.AddMember (this, PropertyBuilder.Name, spec); }
private void createHashMethod(PropertyBuilder propBuild,TypeBuilder typeBuild,FieldBuilder hash) { // First, we'll define the behavior of the "get" property for Hash as a method. MethodBuilder typeHashGet = typeBuild.DefineMethod("GetHash", MethodAttributes.Public, typeof(Hashtable), new Type[] { }); ILGenerator ilg = typeHashGet.GetILGenerator(); ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldfld, hash); ilg.Emit(OpCodes.Ret); // Now, we'll define the behavior of the "set" property for Hash. MethodBuilder typeHashSet = typeBuild.DefineMethod("SetHash", MethodAttributes.Public, null, new Type[] { typeof(Hashtable) }); ilg = typeHashSet.GetILGenerator(); ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldarg_1); ilg.Emit(OpCodes.Stfld, hash); ilg.Emit(OpCodes.Ret); // map the two methods created above to their property propBuild.SetGetMethod(typeHashGet); propBuild.SetSetMethod(typeHashSet); //add the [Browsable(false)] property to the Hash property so it doesnt show up on the property list ConstructorInfo ci = typeof(BrowsableAttribute).GetConstructor(new Type[]{typeof(bool)}); CustomAttributeBuilder cab = new CustomAttributeBuilder(ci,new object[]{false}); propBuild.SetCustomAttribute(cab); }
/* deprecated //IL: // L_0000: newobj instance void Vita.Framework.EntityListProxy`1<class Vita.Framework.SampleEntityImpl.ISampleEntity>::.ctor() // private void CreateListTypeAndListCreatorMethod(EntityInfo entityInfo, TypeBuilder entityTypeBuilder) { //Construct concrete list type from generic EntityListProxy<> type var listGenericType = typeof(ObservableEntityList<>); entityInfo.ClassInfo.ListType = listGenericType.MakeGenericType(entityInfo.EntityType); var listConstr = entityInfo.ClassInfo.ListType.GetConstructor(Type.EmptyTypes); //Now create static factory method var methFlags = MethodAttributes.Static | MethodAttributes.Public; var createListProxyBuilder = entityTypeBuilder.DefineMethod(ListProxyCreatorMethodName, methFlags, typeof(IList), Type.EmptyTypes); var ilGen = createListProxyBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Newobj, listConstr); ilGen.Emit(OpCodes.Ret); } */ /* Getter IL IL_0000: ldarg.0 IL_0001: ldfld ns.EntityBase::Record IL_0006: ldc.i4.1 IL_0007: callvirt instance object ExperimentsApp.StaticMembers.EntityRecord::GetValue(int32) IL_000c: castclass [mscorlib]System.String IL_0011: ret */ private MethodBuilder CreateGetter(TypeBuilder typeBuilder, PropertyBuilder propertyBuilder, int memberIndex, string name = null, bool asPublic = true) { var getterName = name ?? "get_" + propertyBuilder.Name; var attrs = MethodAttributes.SpecialName | MethodAttributes.Virtual | MethodAttributes.HideBySig; if (asPublic) attrs |= MethodAttributes.Public; else attrs |= MethodAttributes.Private; var propType = propertyBuilder.PropertyType; var getter = typeBuilder.DefineMethod(getterName, attrs, propType, Type.EmptyTypes); var ilGen = getter.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldfld, _entityBase_Record); ilGen.Emit(OpCodes.Ldc_I4, memberIndex); ilGen.Emit(OpCodes.Call, _entityRecord_GetValue); if (propType.IsValueType) // || propType.IsEnum) ilGen.Emit(OpCodes.Unbox_Any, propType); else ilGen.Emit(OpCodes.Castclass, propType); ilGen.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getter); return getter; }
public MethodBuilder CreateGetMethod(TypeBuilder Class, PropertyBuilder Property, FieldBuilder Field, Boolean Public, System.Type ReturnType) { String methodName = "get_" + Property.Name; MethodBuilder getMethod = Class.DefineMethod(methodName, BasePropertyMethodAttr, ReturnType, Type.EmptyTypes); ILGenerator getIL = getMethod.GetILGenerator(); getIL.Emit(OpCodes.Ldarg_0); getIL.Emit(OpCodes.Ldfld, Field); getIL.Emit(OpCodes.Ret); Property.SetGetMethod(getMethod); return getMethod; }
protected void DefineBuilders (MemberKind kind, ParametersCompiled parameters) { PropertyBuilder = Parent.TypeBuilder.DefineProperty ( GetFullName (MemberName), PropertyAttributes.None, #if !BOOTSTRAP_BASIC // Requires trunk version mscorlib IsStatic ? 0 : CallingConventions.HasThis, #endif MemberType.GetMetaInfo (), null, null, parameters.GetMetaInfo (), null, null); PropertySpec spec; if (kind == MemberKind.Indexer) spec = new IndexerSpec (Parent.Definition, this, MemberType, parameters, PropertyBuilder, ModFlags); else spec = new PropertySpec (kind, Parent.Definition, this, MemberType, PropertyBuilder, ModFlags); if (Get != null) { spec.Get = Get.Spec; var method = Get.Spec.GetMetaInfo () as MethodBuilder; if (method != null) { PropertyBuilder.SetGetMethod (method); Parent.MemberCache.AddMember (this, method.Name, Get.Spec); } } else { CheckMissingAccessor (kind, parameters, true); } if (Set != null) { spec.Set = Set.Spec; var method = Set.Spec.GetMetaInfo () as MethodBuilder; if (method != null) { PropertyBuilder.SetSetMethod (method); Parent.MemberCache.AddMember (this, method.Name, Set.Spec); } } else { CheckMissingAccessor (kind, parameters, false); } Parent.MemberCache.AddMember (this, PropertyBuilder.Name, spec); }
private static void DefineGetMethod(TypeBuilder newType, PropertyBuilder propertyBuilder, FieldInfo fieldBuilder, PropertyInfo property) { var getMethod = property.GetGetMethod(); var methodBuilder = newType.DefineMethod(getMethod.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual, property.PropertyType, Type.EmptyTypes); var ilg = methodBuilder.GetILGenerator(); ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldfld, fieldBuilder); ilg.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(methodBuilder); var methodInfo = methodBuilder.GetBaseDefinition(); newType.DefineMethodOverride(methodInfo, getMethod); }
private void DefinePropertyGetter(Entity c, Entity p, TypeBuilder t, bool forward, string propname, Type rettype, Type retelemtype, bool functional, PropertyBuilder property) { MethodBuilder method = t.DefineMethod("get_" + propname, MethodAttributes.Public | MethodAttributes.SpecialName, CallingConventions.HasThis, rettype, Type.EmptyTypes); property.SetGetMethod(method); ILGenerator il = method.GetILGenerator(); il.DeclareLocal(typeof(ArrayList)); il.DeclareLocal(typeof(int)); if (retelemtype == typeof(string)) il.DeclareLocal(typeof(string)); else il.DeclareLocal(typeof(Entity)); if (!functional) { // Create array list in local variable 0 il.Emit(OpCodes.Newobj, arraylistconstructor); il.Emit(OpCodes.Stloc_0); } // Push model (arg 0 of Select) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, getmodel); if (forward) { // Push entity (arg 1 to Select) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, getentity); // Push property (arg 2 to Select) il.Emit(OpCodes.Ldstr, p.Uri); il.Emit(OpCodes.Newobj, newentity); } else { // Push property (arg 1 to Select) il.Emit(OpCodes.Ldstr, p.Uri); il.Emit(OpCodes.Newobj, newentity); // Push entity (arg 2 to Select) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, getentity); } // Call select (pushes Resource[] or Entity[]) if (forward) il.Emit(OpCodes.Call, selectobjects); else il.Emit(OpCodes.Call, selectsubjects); // Loop through the statements Label loopstart = il.DefineLabel(); Label loopend = il.DefineLabel(); Label loopcontinue = il.DefineLabel(); il.Emit(OpCodes.Ldc_I4_0); // initialize counter local var 1 il.Emit(OpCodes.Stloc_1); il.MarkLabel(loopstart); il.Emit(OpCodes.Dup); // dup the array il.Emit(OpCodes.Ldlen); // push length of array il.Emit(OpCodes.Ldloc_1); // push counter il.Emit(OpCodes.Ble, loopend); il.Emit(OpCodes.Dup); // dup the array il.Emit(OpCodes.Ldloc_1); // push counter il.Emit(OpCodes.Ldelem_Ref); // pop array, counter, push element // Ensure value is of the right type if (retelemtype == typeof(string)) { // Literal value il.Emit(OpCodes.Isinst, typeof(Literal)); il.Emit(OpCodes.Brfalse, loopcontinue); } else if (forward) { // if !forward, it must be an entity // Ensure entity value il.Emit(OpCodes.Isinst, typeof(Entity)); il.Emit(OpCodes.Brfalse, loopcontinue); } // Because of the br, we've lost the object reference -- load it again il.Emit(OpCodes.Dup); // dup the array il.Emit(OpCodes.Ldloc_1); // push counter il.Emit(OpCodes.Ldelem_Ref); // pop array, counter, push element // Get the value we want to return if (retelemtype == typeof(string)) { // Cast to literal, replace it with its value il.Emit(OpCodes.Castclass, typeof(Literal)); il.Emit(OpCodes.Call, literalvalue); } else { // Cast to entity, push model, replace with bound type il.Emit(OpCodes.Castclass, typeof(Entity)); il.Emit(OpCodes.Ldarg_0); // model il.Emit(OpCodes.Call, getmodel); ConstructorInfo ctor = GetConstructor(retelemtype); il.Emit(OpCodes.Newobj, ctor); } if (!functional) { // We need the ArrayList before this argument. il.Emit(OpCodes.Stloc_2); il.Emit(OpCodes.Ldloc_0); // push ArrayList il.Emit(OpCodes.Ldloc_2); // get back the object il.Emit(OpCodes.Call, arraylistadd); // add to ArrayList il.Emit(OpCodes.Pop); // pop the int32 return value of Add } else { // Store the result, clear the stack, get the result back, and return. il.Emit(OpCodes.Stloc_2); il.Emit(OpCodes.Pop); // the entities array il.Emit(OpCodes.Ldloc_2); il.Emit(OpCodes.Ret); } // increment counter il.MarkLabel(loopcontinue); il.Emit(OpCodes.Ldloc_1); // push counter il.Emit(OpCodes.Ldc_I4_1); // push 1 il.Emit(OpCodes.Add); il.Emit(OpCodes.Stloc_1); // go to start of loop il.Emit(OpCodes.Br, loopstart); il.MarkLabel(loopend); il.Emit(OpCodes.Pop); // pop the Resource[] array if (!functional) { // Load array list and convert to array, and return. il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldtoken, retelemtype); il.Emit(OpCodes.Call, gettypefromhandle); il.Emit(OpCodes.Call, arraylisttoarray); il.Emit(OpCodes.Castclass, rettype); } else { il.Emit(OpCodes.Ldnull); } il.Emit(OpCodes.Ret); }
/// <summary> /// Creates the body of a property getter /// </summary> /// <param name="generatedTypeBuilder"></param> /// <param name="p"></param> /// <param name="property"></param> /// <param name="getDecl"></param> /// <param name="logicField"></param> private void CreatePropertyGetMethod(TypeBuilderHelper generatedTypeBuilder, PropertyInfo p, PropertyBuilder property, MethodInfo getDecl, FieldInfo logicField) { //set setter name and return type var setterName = getDecl == null ? "get_" + p.Name : getDecl.Name; var returnType = getDecl == null ? p.PropertyType : getDecl.ReturnType; //determine security attributes var methodAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual; //create setter method var getBuilder = generatedTypeBuilder.DefineMethod(setterName, methodAttributes, returnType, null); //emit IL opcode getBuilder .Emitter .nop .ldarg_0 .ldfld(logicField) .ldstr(p.Name) //this.LogicBase<[logicField.FieldType]>.GetProperty([methodName]) .callvirt(Reflect<LogicBase>.GetMethod(x => x.GetProperty<object>(string.Empty)).MakeGenericMethod(p.PropertyType)) .ret(); //apply the created method to the getter property.SetGetMethod(getBuilder); }
public bool EmitMember( TypeBuilder typeBuilder, EdmMember member, PropertyBuilder propertyBuilder, PropertyInfo baseProperty, BaseProxyImplementor baseImplementor) { if (_members.Contains(member)) { var baseGetter = baseProperty.GetGetMethod(true); const MethodAttributes getterAttributes = MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual; var getterAccess = baseGetter.Attributes & MethodAttributes.MemberAccessMask; // Define field to store interceptor Func // Signature of interceptor Func delegate is as follows: // // bool intercept(ProxyType proxy, PropertyType propertyValue) // // where // PropertyType is the type of the Property, such as ICollection<Customer>, // ProxyType is the type of the proxy object, // propertyValue is the value returned from the proxied type's property getter. var interceptorType = typeof(Func<,,>).MakeGenericType(typeBuilder, baseProperty.PropertyType, typeof(bool)); var interceptorInvoke = TypeBuilder.GetMethod(interceptorType, typeof(Func<,,>).GetMethod("Invoke")); var interceptorField = typeBuilder.DefineField( GetInterceptorFieldName(baseProperty.Name), interceptorType, FieldAttributes.Private | FieldAttributes.Static); // Define a property getter override in the proxy type var getterBuilder = typeBuilder.DefineMethod( "get_" + baseProperty.Name, getterAccess | getterAttributes, baseProperty.PropertyType, Type.EmptyTypes); var generator = getterBuilder.GetILGenerator(); // Emit instructions for the following call: // T value = base.SomeProperty; // if(this._interceptorForSomeProperty(this, value)) // { return value; } // return base.SomeProperty; // where _interceptorForSomeProperty represents the interceptor Func field. var lableTrue = generator.DefineLabel(); generator.DeclareLocal(baseProperty.PropertyType); // T value generator.Emit(OpCodes.Ldarg_0); // call base.SomeProperty generator.Emit(OpCodes.Call, baseGetter); // call to base property getter generator.Emit(OpCodes.Stloc_0); // value = result generator.Emit(OpCodes.Ldarg_0); // load this generator.Emit(OpCodes.Ldfld, interceptorField); // load this._interceptor generator.Emit(OpCodes.Ldarg_0); // load this generator.Emit(OpCodes.Ldloc_0); // load value generator.Emit(OpCodes.Callvirt, interceptorInvoke); // call to interceptor delegate with (this, value) generator.Emit(OpCodes.Brtrue_S, lableTrue); // if true, just return generator.Emit(OpCodes.Ldarg_0); // else, call the base propertty getter again generator.Emit(OpCodes.Call, baseGetter); // call to base property getter generator.Emit(OpCodes.Ret); generator.MarkLabel(lableTrue); generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getterBuilder); baseImplementor.AddBasePropertyGetter(baseProperty); return true; } return false; }
private static void EmitProperty( PropertyInfo info, string name, string convertGet, Type tGetReturnType, string invokeGet, Type[] indexParamTypes, MethodInfo setMethod, string invokeSet, Type[] setParamTypes, TypeBuilder typeBuilder, MethodBuilder getMethodBuilder, Type callSite, Type contextType, Type tConvertFuncType, Type invokeGetFuncType, PropertyBuilder tMp, Type invokeSetFuncType, bool defaultImp) { if (indexParamTypes == null) { throw new ArgumentNullException("indexParamTypes"); } var tIlGen = getMethodBuilder.GetILGenerator(); var tConvertCallsiteField = callSite.GetFieldEvenIfGeneric(convertGet); var tReturnLocal = tIlGen.DeclareLocal(tGetReturnType); using (tIlGen.EmitBranchTrue(gen => gen.Emit(OpCodes.Ldsfld, tConvertCallsiteField))) { tIlGen.EmitDynamicConvertBinder(CSharpBinderFlags.None, tGetReturnType, contextType); tIlGen.EmitCallsiteCreate(tConvertFuncType); tIlGen.Emit(OpCodes.Stsfld, tConvertCallsiteField); } var tInvokeGetCallsiteField = callSite.GetFieldEvenIfGeneric(invokeGet); using (tIlGen.EmitBranchTrue(gen => gen.Emit(OpCodes.Ldsfld, tInvokeGetCallsiteField))) { tIlGen.EmitDynamicGetBinder(CSharpBinderFlags.None, name, contextType, indexParamTypes); tIlGen.EmitCallsiteCreate(invokeGetFuncType); tIlGen.Emit(OpCodes.Stsfld, tInvokeGetCallsiteField); } tIlGen.Emit(OpCodes.Ldsfld, tConvertCallsiteField); tIlGen.Emit(OpCodes.Ldfld, tConvertCallsiteField.FieldType.GetFieldEvenIfGeneric("Target")); tIlGen.Emit(OpCodes.Ldsfld, tConvertCallsiteField); tIlGen.Emit(OpCodes.Ldsfld, tInvokeGetCallsiteField); tIlGen.Emit(OpCodes.Ldfld, tInvokeGetCallsiteField.FieldType.GetFieldEvenIfGeneric("Target")); tIlGen.Emit(OpCodes.Ldsfld, tInvokeGetCallsiteField); tIlGen.Emit(OpCodes.Ldarg_0); tIlGen.Emit(OpCodes.Call, typeof (ActLikeProxy).GetProperty("Original").GetGetMethod()); for (var i = 1; i <= indexParamTypes.Length; i++) { tIlGen.EmitLoadArgument(i); } tIlGen.EmitCallInvokeFunc(invokeGetFuncType); tIlGen.EmitCallInvokeFunc(tConvertFuncType); tIlGen.EmitStoreLocation(tReturnLocal.LocalIndex); var tReturnLabel = tIlGen.DefineLabel(); tIlGen.Emit(OpCodes.Br_S, tReturnLabel); tIlGen.MarkLabel(tReturnLabel); tIlGen.EmitLoadLocation(tReturnLocal.LocalIndex); tIlGen.Emit(OpCodes.Ret); tMp.SetGetMethod(getMethodBuilder); if (setMethod != null) { MethodAttributes tPublicPrivate = MethodAttributes.Public; var tPrefixedSet = setMethod.Name; if (!defaultImp) { tPublicPrivate = MethodAttributes.Private; tPrefixedSet = String.Format("{0}.{1}", info.DeclaringType.FullName, tPrefixedSet); } var tSetMethodBuilder = typeBuilder.DefineMethod(tPrefixedSet, tPublicPrivate | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot, null, setParamTypes); if (!defaultImp) { typeBuilder.DefineMethodOverride(tSetMethodBuilder, info.GetSetMethod()); } foreach (var tParam in info.GetSetMethod().GetParameters()) { tSetMethodBuilder.DefineParameter(tParam.Position + 1, AttributesForParam(tParam), tParam.Name); } tIlGen = tSetMethodBuilder.GetILGenerator(); var tSetCallsiteField = callSite.GetFieldEvenIfGeneric(invokeSet); using (tIlGen.EmitBranchTrue(gen => gen.Emit(OpCodes.Ldsfld, tSetCallsiteField))) { tIlGen.EmitDynamicSetBinder(CSharpBinderFlags.None, name, contextType, setParamTypes); tIlGen.EmitCallsiteCreate(invokeSetFuncType); tIlGen.Emit(OpCodes.Stsfld, tSetCallsiteField); } tIlGen.Emit(OpCodes.Ldsfld, tSetCallsiteField); tIlGen.Emit(OpCodes.Ldfld, tSetCallsiteField.FieldType.GetFieldEvenIfGeneric("Target")); tIlGen.Emit(OpCodes.Ldsfld, tSetCallsiteField); tIlGen.Emit(OpCodes.Ldarg_0); tIlGen.Emit(OpCodes.Call, typeof (ActLikeProxy).GetProperty("Original").GetGetMethod()); for (var i = 1; i <= setParamTypes.Length; i++) { tIlGen.EmitLoadArgument(i); } tIlGen.EmitCallInvokeFunc(invokeSetFuncType); tIlGen.Emit(OpCodes.Pop); tIlGen.Emit(OpCodes.Ret); tMp.SetSetMethod(tSetMethodBuilder); } }
/// <summary> /// Generate the declaration for the IgnoresAccessChecksToAttribute type. /// This attribute will be both defined and used in the dynamic assembly. /// Each usage identifies the name of the assembly containing non-public /// types the dynamic assembly needs to access. Normally those types /// would be inaccessible, but this attribute allows them to be visible. /// It works like a reverse InternalsVisibleToAttribute. /// This method returns the ConstructorInfo of the generated attribute. /// </summary> public static ConstructorInfo AddToModule(ModuleBuilder mb) { TypeBuilder attributeTypeBuilder = mb.DefineType("System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute", TypeAttributes.Public | TypeAttributes.Class, typeof(Attribute)); // Create backing field as: // private string assemblyName; FieldBuilder assemblyNameField = attributeTypeBuilder.DefineField("assemblyName", typeof(string), FieldAttributes.Private); // Create ctor as: // public IgnoresAccessChecksToAttribute(string) ConstructorBuilder constructorBuilder = attributeTypeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { assemblyNameField.FieldType }); ILGenerator il = constructorBuilder.GetILGenerator(); // Create ctor body as: // this.assemblyName = {ctor parameter 0} il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg, 1); il.Emit(OpCodes.Stfld, assemblyNameField); // return il.Emit(OpCodes.Ret); // Define property as: // public string AssemblyName {get { return this.assemblyName; } } PropertyBuilder propertyBuilder = attributeTypeBuilder.DefineProperty( "AssemblyName", PropertyAttributes.None, CallingConventions.HasThis, returnType: typeof(string), parameterTypes: null); MethodBuilder getterMethodBuilder = attributeTypeBuilder.DefineMethod( "get_AssemblyName", MethodAttributes.Public, CallingConventions.HasThis, returnType: typeof(string), parameterTypes: null); propertyBuilder.SetGetMethod(getterMethodBuilder); // Generate body: // return this.assemblyName; il = getterMethodBuilder.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, assemblyNameField); il.Emit(OpCodes.Ret); // Generate the AttributeUsage attribute for this attribute type: // [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] TypeInfo attributeUsageTypeInfo = typeof(AttributeUsageAttribute).GetTypeInfo(); // Find the ctor that takes only AttributeTargets ConstructorInfo attributeUsageConstructorInfo = attributeUsageTypeInfo.DeclaredConstructors .Single(c => c.GetParameters().Length == 1 && c.GetParameters()[0].ParameterType == typeof(AttributeTargets)); // Find the property to set AllowMultiple PropertyInfo allowMultipleProperty = attributeUsageTypeInfo.DeclaredProperties .Single(f => string.Equals(f.Name, "AllowMultiple")); // Create a builder to construct the instance via the ctor and property CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(attributeUsageConstructorInfo, new object[] { AttributeTargets.Assembly }, new PropertyInfo[] { allowMultipleProperty }, new object[] { true }); // Attach this attribute instance to the newly defined attribute type attributeTypeBuilder.SetCustomAttribute(customAttributeBuilder); // Make the TypeInfo real so the constructor can be used. return(attributeTypeBuilder.CreateTypeInfo() !.DeclaredConstructors.Single()); }
private static void EmitGetter(TypeBuilder proxyTypeBuilder, PropertyBuilder propertyBuilder, FieldBuilder self, PropertyInfo declaration, PropertyInfo delegatedProperty, Type propertyType, Type[] indexTypes) { var getter = declaration.GetGetMethod(); if (getter != null) { var getterBuilder = proxyTypeBuilder.DefineMethod("get_" + declaration.Name, PropertyAttribute, propertyType, indexTypes); var generator = getterBuilder.GetILGenerator(); if (delegatedProperty == null) { generator.ThrowException(typeof(NotSupportedException)); } else { var delegatedGetter = delegatedProperty.GetGetMethod(); EmitImplementation(generator, self, delegatedGetter, indexTypes); propertyBuilder.SetGetMethod(getterBuilder); } } }