// TODO: merge method and mb public ReturnParameter (MemberCore method, MethodBuilder mb, Location location) { this.method = method; try { builder = mb.DefineParameter (0, ParameterAttributes.None, ""); } catch (ArgumentOutOfRangeException) { method.Compiler.Report.RuntimeMissingSupport (location, "custom attributes on the return type"); } }
private void VerifyMethodInfo(MethodInfo methodInfo, MethodBuilder builder, Type returnType) { if (methodInfo == null) { Assert.Null(builder); } else { Assert.Equal(methodInfo.Name, builder.Name); Assert.Equal(methodInfo.ReturnType, returnType); } }
static void EmitTestEvents (TypeBuilder genericFoo) { MethodBuilder mb = genericFoo.DefineMethod ("TestEvents", MethodAttributes.Public, typeof (void), null); ILGenerator il = mb.GetILGenerator (); for (int i = 0; i < 20; ++i) il.Emit (OpCodes.Nop); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldnull); il.Emit (OpCodes.Callvirt, targetMethod); il.Emit (OpCodes.Ret); testEvents = mb; }
static void EmitTargetMethod (TypeBuilder genericFoo) { MethodBuilder mb = genericFoo.DefineMethod ("TargetMethod", MethodAttributes.Public, typeof (void), new Type[] {typeof (object) }); ILGenerator il = mb.GetILGenerator (); for (int i = 0; i < 20; ++i) il.Emit (OpCodes.Nop); il.Emit (OpCodes.Ldtoken, genericArgs [0]); il.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle")); il.Emit (OpCodes.Call, typeof (Console).GetMethod ("WriteLine", new Type[] { typeof (object) })); il.Emit (OpCodes.Ret); targetMethod = mb; }
/// <summary> /// Constructor /// </summary> /// <param name="typeBuilder">Type builder</param> /// <param name="name">Name of the property</param> /// <param name="attributes">Attributes for the property (public, private, etc.)</param> /// <param name="getMethodAttributes">Get method attributes</param> /// <param name="setMethodAttributes">Set method attributes</param> /// <param name="propertyType">Property type for the property</param> /// <param name="parameters">Parameter types for the property</param> public DefaultPropertyBuilder(TypeBuilder typeBuilder, string name, PropertyAttributes attributes, MethodAttributes getMethodAttributes, MethodAttributes setMethodAttributes, Type propertyType, IEnumerable<Type> parameters) { if (typeBuilder == null) throw new ArgumentNullException("typeBuilder"); if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); Name = name; Type = typeBuilder; Attributes = attributes; GetMethodAttributes = getMethodAttributes; SetMethodAttributes = setMethodAttributes; DataType = propertyType; Parameters = new List<ParameterBuilder>(); if (parameters != null) { int x = 1; foreach (var parameter in parameters) { Parameters.Add(new ParameterBuilder(parameter, x)); ++x; } } Field = new FieldBuilder(Type, "_" + name + "field", propertyType, FieldAttributes.Private); Builder = Type.Builder.DefineProperty(name, attributes, propertyType, (parameters != null && parameters.Count() > 0) ? parameters.ToArray() : System.Type.EmptyTypes); GetMethod = new MethodBuilder(Type, "get_" + name, getMethodAttributes, parameters, propertyType); GetMethod.Generator.Emit(OpCodes.Ldarg_0); GetMethod.Generator.Emit(OpCodes.Ldfld, Field.Builder); GetMethod.Generator.Emit(OpCodes.Ret); var setParameters = new List<Type>(); if (parameters != null) { setParameters.AddRange(parameters); } setParameters.Add(propertyType); SetMethod = new MethodBuilder(Type, "set_" + name, setMethodAttributes, setParameters, typeof (void)); SetMethod.Generator.Emit(OpCodes.Ldarg_0); SetMethod.Generator.Emit(OpCodes.Ldarg_1); SetMethod.Generator.Emit(OpCodes.Stfld, Field.Builder); SetMethod.Generator.Emit(OpCodes.Ret); Builder.SetGetMethod(GetMethod.Builder); Builder.SetSetMethod(SetMethod.Builder); }
private static void VerifyGenericArguments(MethodBuilder method, GenericTypeParameterBuilder[] expected) { Type[] genericArguments = method.GetGenericArguments(); if (expected == null) { Assert.Null(genericArguments); } else { Assert.Equal(expected.Length, genericArguments.Length); for (int i = 0; i < genericArguments.Length; ++i) { Assert.True(expected[i].Equals(genericArguments[i])); } } }
/// <summary> /// Constructor /// </summary> /// <param name="TypeBuilder">Type builder</param> /// <param name="Name">Name of the property</param> /// <param name="Attributes">Attributes for the property (public, private, etc.)</param> /// <param name="GetMethodAttributes">Get method attributes</param> /// <param name="SetMethodAttributes">Set method attributes</param> /// <param name="PropertyType">Property type for the property</param> /// <param name="Parameters">Parameter types for the property</param> public DefaultPropertyBuilder(TypeBuilder TypeBuilder, string Name, PropertyAttributes Attributes, MethodAttributes GetMethodAttributes, MethodAttributes SetMethodAttributes, Type PropertyType, List<Type> Parameters) : base() { if (TypeBuilder == null) throw new ArgumentNullException("TypeBuilder"); if (string.IsNullOrEmpty(Name)) throw new ArgumentNullException("Name"); this.Name = Name; this.Type = TypeBuilder; this.Attributes = Attributes; this.GetMethodAttributes = GetMethodAttributes; this.SetMethodAttributes = SetMethodAttributes; this.DataType = PropertyType; this.Parameters = new List<ParameterBuilder>(); if (Parameters != null) { int x = 1; foreach (Type Parameter in Parameters) { this.Parameters.Add(new ParameterBuilder(Parameter, x)); ++x; } } Field = new FieldBuilder(Type, "_" + Name + "field", PropertyType, FieldAttributes.Private); Builder = Type.Builder.DefineProperty(Name, Attributes, PropertyType, (Parameters != null && Parameters.Count > 0) ? Parameters.ToArray() : System.Type.EmptyTypes); GetMethod = new MethodBuilder(Type, "get_" + Name, GetMethodAttributes, Parameters, PropertyType); GetMethod.Generator.Emit(OpCodes.Ldarg_0); GetMethod.Generator.Emit(OpCodes.Ldfld, Field.Builder); GetMethod.Generator.Emit(OpCodes.Ret); List<Type> SetParameters = new List<System.Type>(); if (Parameters != null) { SetParameters.AddRange(Parameters); } SetParameters.Add(PropertyType); SetMethod = new MethodBuilder(Type, "set_" + Name, SetMethodAttributes, SetParameters, typeof(void)); SetMethod.Generator.Emit(OpCodes.Ldarg_0); SetMethod.Generator.Emit(OpCodes.Ldarg_1); SetMethod.Generator.Emit(OpCodes.Stfld, Field.Builder); SetMethod.Generator.Emit(OpCodes.Ret); Builder.SetGetMethod(GetMethod.Builder); Builder.SetSetMethod(SetMethod.Builder); }
public CodeGen(Stmt stmt, string moduleName) { if (string.IsNullOrEmpty(moduleName)) throw new ArgumentException("must have a module name", "moduleName"); _stmt = stmt; _moduleName = moduleName; if (Path.GetFileName(moduleName) != moduleName) throw new Exception("can only output into current directory!"); var filename = Path.GetFileNameWithoutExtension(moduleName); var asmName = new AssemblyName(filename); _asmb = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Save); _modb = _asmb.DefineDynamicModule(moduleName); _typeBuilder = _modb.DefineType("Foo"); _methb = _typeBuilder.DefineMethod("Main", MethodAttributes.Static, typeof(void), Type.EmptyTypes); _il = _methb.GetILGenerator(); SymbolTable = new Dictionary<string, LocalBuilder>(); }
/// <summary> /// Constructor /// </summary> /// <param name="TypeBuilder">Type builder</param> /// <param name="Name">Name of the property</param> /// <param name="Attributes">Attributes for the property (public, private, etc.)</param> /// <param name="GetMethodAttributes">Get method attributes</param> /// <param name="SetMethodAttributes">Set method attributes</param> /// <param name="PropertyType">Property type for the property</param> /// <param name="Parameters">Parameter types for the property</param> public PropertyBuilder(TypeBuilder TypeBuilder, string Name, PropertyAttributes Attributes, MethodAttributes GetMethodAttributes, MethodAttributes SetMethodAttributes, Type PropertyType, IEnumerable<Type> Parameters) : base() { Contract.Requires<ArgumentNullException>(TypeBuilder!=null,"TypeBuilder"); Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(Name),"Name"); this.Name = Name; this.Type = TypeBuilder; this.Attributes = Attributes; this.GetMethodAttributes = GetMethodAttributes; this.SetMethodAttributes = SetMethodAttributes; this.DataType = PropertyType; this.Parameters = new List<ParameterBuilder>(); if (Parameters != null) { int x = 1; foreach (Type Parameter in Parameters) { this.Parameters.Add(new ParameterBuilder(Parameter, x)); ++x; } } Builder = Type.Builder.DefineProperty(Name, Attributes, PropertyType, (Parameters != null && Parameters.Count() > 0) ? Parameters.ToArray() : System.Type.EmptyTypes); GetMethod = new MethodBuilder(Type, "get_" + Name, GetMethodAttributes, Parameters, PropertyType); List<Type> SetParameters = new List<System.Type>(); if (Parameters != null) SetParameters.AddRange(Parameters); SetParameters.Add(PropertyType); SetMethod = new MethodBuilder(Type, "set_" + Name, SetMethodAttributes, SetParameters, typeof(void)); Builder.SetGetMethod(GetMethod.Builder); Builder.SetSetMethod(SetMethod.Builder); }
internal void SetGhostMethod(MethodBuilder mb) { this.ghostMethod = mb; }
public void ToString_ShowILOffset() { string AssemblyName = "ExceptionTestAssembly.dll"; string SourceTestAssemblyPath = Path.Combine(Environment.CurrentDirectory, AssemblyName); string regPattern = @":token 0x([a-f0-9]*)\+0x([a-f0-9]*)"; // Normal loading case RemoteExecutor.Invoke((asmPath, asmName, p) => { AppContext.SetSwitch("Switch.System.Diagnostics.StackTrace.ShowILOffsets", true); var asm = Assembly.LoadFrom(asmPath); try { asm.GetType("Program").GetMethod("Foo").Invoke(null, null); } catch (Exception e) { Assert.Contains(asmName, e.InnerException.StackTrace); Assert.True(Regex.Match(e.InnerException.StackTrace, p).Success); } }, SourceTestAssemblyPath, AssemblyName, regPattern).Dispose(); // Assembly.Load(Byte[]) case RemoteExecutor.Invoke((asmPath, asmName, p) => { AppContext.SetSwitch("Switch.System.Diagnostics.StackTrace.ShowILOffsets", true); var inMemBlob = File.ReadAllBytes(asmPath); var asm2 = Assembly.Load(inMemBlob); try { asm2.GetType("Program").GetMethod("Foo").Invoke(null, null); } catch (Exception e) { Assert.Contains(asmName, e.InnerException.StackTrace); Assert.True(Regex.Match(e.InnerException.StackTrace, p).Success); } }, SourceTestAssemblyPath, AssemblyName, regPattern).Dispose(); // AssmblyBuilder.DefineDynamicAssembly() case RemoteExecutor.Invoke((p) => { AppContext.SetSwitch("Switch.System.Diagnostics.StackTrace.ShowILOffsets", true); AssemblyName asmName = new AssemblyName("ExceptionTestAssembly"); AssemblyBuilder asmBldr = AssemblyBuilder.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run); ModuleBuilder modBldr = asmBldr.DefineDynamicModule(asmName.Name); TypeBuilder tBldr = modBldr.DefineType("Program"); MethodBuilder mBldr = tBldr.DefineMethod("Foo", MethodAttributes.Public | MethodAttributes.Static, null, null); ILGenerator ilGen = mBldr.GetILGenerator(); ilGen.ThrowException(typeof(NullReferenceException)); ilGen.Emit(OpCodes.Ret); Type t = tBldr.CreateType(); try { t.InvokeMember("Foo", BindingFlags.InvokeMethod, null, null, null); } catch (Exception e) { Assert.Contains("RefEmit_InMemoryManifestModule", e.InnerException.StackTrace); Assert.True(Regex.Match(e.InnerException.StackTrace, p).Success); } }, regPattern).Dispose(); }
public virtual void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa) { if (builder != null) throw new InternalErrorException ("builder already exists"); var pattrs = ParametersCompiled.GetParameterAttribute (modFlags); if (HasOptionalExpression) pattrs |= ParameterAttributes.Optional; if (mb == null) builder = cb.DefineParameter (index, pattrs, Name); else builder = mb.DefineParameter (index, pattrs, Name); if (OptAttributes != null) OptAttributes.Emit (); if (HasDefaultValue) { // // Emit constant values for true constants only, the other // constant-like expressions will rely on default value expression // var def_value = DefaultValue; Constant c = def_value != null ? def_value.Child as Constant : default_expr as Constant; if (c != null) { if (c.Type.BuiltinType == BuiltinTypeSpec.Type.Decimal) { pa.DecimalConstant.EmitAttribute (builder, (decimal) c.GetValue (), c.Location); } else { builder.SetConstant (c.GetValue ()); } } else if (default_expr.Type.IsStruct) { // // Handles special case where default expression is used with value-type // // void Foo (S s = default (S)) {} // builder.SetConstant (null); } } if (parameter_type != null) { if (parameter_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { pa.Dynamic.EmitAttribute (builder); } else if (parameter_type.HasDynamicElement) { pa.Dynamic.EmitAttribute (builder, parameter_type, Location); } } }
void enterLambda(MethodBuilder method) { this.PreviousLineNumber = 0; this.methods.add(method); this.Generator = method.CodeGenerator; }
static TypeAccessor CreateNew(Type type) { //#if !NO_DYNAMIC // if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type)) // { // return DynamicAccessor.Singleton; // } //#endif PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); ConstructorInfo ctor = null; if (type.IsClass && !type.IsAbstract) { ctor = type.GetConstructor(Type.EmptyTypes); } ILGenerator il; if (!IsFullyPublic(type)) { DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(object), typeof(string) }, type, true), dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(object), typeof(string), typeof(object) }, type, true); WriteGetter(dynGetter.GetILGenerator(), type, props, fields, true); WriteSetter(dynSetter.GetILGenerator(), type, props, fields, true); DynamicMethod dynCtor = null; if (ctor != null) { dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), Type.EmptyTypes, type, true); il = dynCtor.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); } return(new DelegateAccessor( (Func <object, string, object>)dynGetter.CreateDelegate(typeof(Func <object, string, object>)), (Action <object, string, object>)dynSetter.CreateDelegate(typeof(Action <object, string, object>)), dynCtor == null ? null : (Func <object>)dynCtor.CreateDelegate(typeof(Func <object>)))); } // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders if (assembly == null) { AssemblyName name = new AssemblyName("FastMember_dynamic"); assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); module = assembly.DefineDynamicModule(name.Name); } TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + Interlocked.Increment(ref counter), (typeof(TypeAccessor).Attributes | TypeAttributes.Sealed) & ~TypeAttributes.Abstract, typeof(TypeAccessor)); tb.DefineDefaultConstructor(MethodAttributes.Public); PropertyInfo indexer = typeof(TypeAccessor).GetProperty("Item"); MethodInfo baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod(); MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) }); il = body.GetILGenerator(); WriteGetter(il, type, props, fields, false); tb.DefineMethodOverride(body, baseGetter); body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) }); il = body.GetILGenerator(); WriteSetter(il, type, props, fields, false); tb.DefineMethodOverride(body, baseSetter); if (ctor != null) { MethodInfo baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod(); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof(bool), Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); baseMethod = typeof(TypeAccessor).GetMethod("CreateNew"); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, typeof(object), Type.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); } return((TypeAccessor)Activator.CreateInstance(tb.CreateType())); }
/// <summary> /// Calls a method on this variable /// </summary> /// <param name="Method">Method</param> /// <param name="Parameters">Parameters sent in</param> /// <returns>Variable returned by the function (if one exists, null otherwise)</returns> public virtual VariableBase Call(MethodBuilder Method, object[] Parameters = null) { if (Method == null) throw new ArgumentNullException("Method"); return Call(Method.Builder, Parameters); }
/// <summary> /// Calls a method on this variable /// </summary> /// <param name="Method">Method</param> /// <param name="Parameters">Parameters sent in</param> /// <returns>Variable returned by the function (if one exists, null otherwise)</returns> public virtual VariableBase Call(MethodBuilder Method, object[] Parameters = null) { Contract.Requires<ArgumentNullException>(Method!=null,"Method"); return Call(Method.Builder, Parameters); }
internal void AddInterfaceImpl(Type iface) { // If necessary, generate an attribute to permit visibility // to internal types. _assembly.EnsureTypeIsVisible(iface); _tb.AddInterfaceImplementation(iface); // AccessorMethods -> Metadata mappings. var propertyMap = new Dictionary <MethodInfo, PropertyAccessorInfo>(MethodInfoEqualityComparer.Instance); foreach (PropertyInfo pi in iface.GetRuntimeProperties()) { var ai = new PropertyAccessorInfo(pi.GetMethod, pi.SetMethod); if (pi.GetMethod != null) { propertyMap[pi.GetMethod] = ai; } if (pi.SetMethod != null) { propertyMap[pi.SetMethod] = ai; } } var eventMap = new Dictionary <MethodInfo, EventAccessorInfo>(MethodInfoEqualityComparer.Instance); foreach (EventInfo ei in iface.GetRuntimeEvents()) { var ai = new EventAccessorInfo(ei.AddMethod, ei.RemoveMethod, ei.RaiseMethod); if (ei.AddMethod != null) { eventMap[ei.AddMethod] = ai; } if (ei.RemoveMethod != null) { eventMap[ei.RemoveMethod] = ai; } if (ei.RaiseMethod != null) { eventMap[ei.RaiseMethod] = ai; } } foreach (MethodInfo mi in iface.GetRuntimeMethods()) { MethodBuilder mdb = AddMethodImpl(mi); PropertyAccessorInfo associatedProperty; if (propertyMap.TryGetValue(mi, out associatedProperty)) { if (MethodInfoEqualityComparer.Instance.Equals(associatedProperty.InterfaceGetMethod, mi)) { associatedProperty.GetMethodBuilder = mdb; } else { associatedProperty.SetMethodBuilder = mdb; } } EventAccessorInfo associatedEvent; if (eventMap.TryGetValue(mi, out associatedEvent)) { if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceAddMethod, mi)) { associatedEvent.AddMethodBuilder = mdb; } else if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceRemoveMethod, mi)) { associatedEvent.RemoveMethodBuilder = mdb; } else { associatedEvent.RaiseMethodBuilder = mdb; } } } foreach (PropertyInfo pi in iface.GetRuntimeProperties()) { PropertyAccessorInfo ai = propertyMap[pi.GetMethod ?? pi.SetMethod]; PropertyBuilder pb = _tb.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, pi.GetIndexParameters().Select(p => p.ParameterType).ToArray()); if (ai.GetMethodBuilder != null) { pb.SetGetMethod(ai.GetMethodBuilder); } if (ai.SetMethodBuilder != null) { pb.SetSetMethod(ai.SetMethodBuilder); } } foreach (EventInfo ei in iface.GetRuntimeEvents()) { EventAccessorInfo ai = eventMap[ei.AddMethod ?? ei.RemoveMethod]; EventBuilder eb = _tb.DefineEvent(ei.Name, ei.Attributes, ei.EventHandlerType); if (ai.AddMethodBuilder != null) { eb.SetAddOnMethod(ai.AddMethodBuilder); } if (ai.RemoveMethodBuilder != null) { eb.SetRemoveOnMethod(ai.RemoveMethodBuilder); } if (ai.RaiseMethodBuilder != null) { eb.SetRaiseMethod(ai.RaiseMethodBuilder); } } }
private static void OverrideGetterOrSetter(TypeBuilder typeBuilder, MethodInfo getterOrSetter, MethodBuilder getterOrSetterBuilder) { if (getterOrSetter == null) { return; } typeBuilder.DefineMethodOverride(getterOrSetterBuilder, getterOrSetter); foreach (var builder in getterOrSetter.CustomAttributes.Select(CreateCustomAttributeBuilder)) { getterOrSetterBuilder.SetCustomAttribute(builder); } }
/// <summary> /// With properties and constructor /// </summary> /// <param name="builder"></param> /// <param name="Dictionary<string"></param> /// <param name="fields"></param> /// <returns></returns> private static TypeBuilder WithPropertiesAndConstructor( this TypeBuilder typeBuilder, List <KeyValuePair <string, Type> > properties ) { // constructor definition Type[] parameterTypes = properties .Select(p => p.Value) .ToArray(); ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, parameterTypes ); ILGenerator ctor = constructorBuilder.GetILGenerator(); ctor.Emit(OpCodes.Ldarg_0); ctor.Emit( OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes) ); // properties for (int index = 0; index < properties.Count(); index++) { var prop = properties.ElementAt(index); FieldBuilder fieldBuilder = typeBuilder.DefineField( $"_{prop.Key}", prop.Value, FieldAttributes.Private ); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty( prop.Key, PropertyAttributes.None, prop.Value, Type.EmptyTypes ); MethodBuilder getter = typeBuilder.DefineMethod( $"get_{prop.Key}", MethodAttributes.Public, prop.Value, Type.EmptyTypes ); ILGenerator getterIL = getter.GetILGenerator(); getterIL.Emit(OpCodes.Ldarg_0); getterIL.Emit(OpCodes.Ldfld, fieldBuilder); getterIL.Emit(OpCodes.Ret); MethodBuilder setter = typeBuilder.DefineMethod( $"set_{prop.Key}", MethodAttributes.Public, typeof(void), new Type[] { prop.Value } ); ILGenerator setterIL = setter.GetILGenerator(); setterIL.Emit(OpCodes.Ldarg_0); setterIL.Emit(OpCodes.Ldarg_1); setterIL.Emit(OpCodes.Stfld, fieldBuilder); setterIL.Emit(OpCodes.Ret); propertyBuilder.SetGetMethod(getter); propertyBuilder.SetSetMethod(setter); ctor.Emit(OpCodes.Ldarg_0); ctor.Emit(OpCodes.Ldarg, index + 1); ctor.Emit(OpCodes.Stfld, fieldBuilder); } ctor.Emit(OpCodes.Ret); return(typeBuilder); }
/// <summary> /// GetDispatcher is responsible for creating a class that provides /// an appropriate managed callback method for a given delegate type. /// </summary> private Type GetDispatcher(Type dtype) { // If a dispatcher type for the given delegate type has already // been generated, get it from the cache. The cache maps delegate // types to generated dispatcher types. A possible optimization // for the future would be to generate dispatcher types based on // unique signatures rather than delegate types, since multiple // delegate types with the same sig could use the same dispatcher. object item = cache[dtype]; if (item != null) { return((Type)item); } string name = "__" + dtype.FullName + "Dispatcher"; name = name.Replace('.', '_'); name = name.Replace('+', '_'); TypeBuilder tb = codeGenerator.DefineType(name, basetype); // Generate a constructor for the generated type that calls the // appropriate constructor of the Dispatcher base type. MethodAttributes ma = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var cc = CallingConventions.Standard; Type[] args = { ptrtype, typetype }; ConstructorBuilder cb = tb.DefineConstructor(ma, cc, args); ConstructorInfo ci = basetype.GetConstructor(args); ILGenerator il = cb.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Call, ci); il.Emit(OpCodes.Ret); // Method generation: we generate a method named "Invoke" on the // dispatcher type, whose signature matches the delegate type for // which it is generated. The method body simply packages the // arguments and hands them to the Dispatch() method, which deals // with converting the arguments, calling the Python method and // converting the result of the call. MethodInfo method = dtype.GetMethod("Invoke"); ParameterInfo[] pi = method.GetParameters(); var signature = new Type[pi.Length]; for (var i = 0; i < pi.Length; i++) { signature[i] = pi[i].ParameterType; } MethodBuilder mb = tb.DefineMethod("Invoke", MethodAttributes.Public, method.ReturnType, signature); ConstructorInfo ctor = listtype.GetConstructor(Type.EmptyTypes); MethodInfo dispatch = basetype.GetMethod("Dispatch"); MethodInfo add = listtype.GetMethod("Add"); il = mb.GetILGenerator(); il.DeclareLocal(listtype); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Stloc_0); for (var c = 0; c < signature.Length; c++) { Type t = signature[c]; il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg_S, (byte)(c + 1)); if (t.IsValueType) { il.Emit(OpCodes.Box, t); } il.Emit(OpCodes.Callvirt, add); il.Emit(OpCodes.Pop); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Call, dispatch); if (method.ReturnType == voidtype) { il.Emit(OpCodes.Pop); } else if (method.ReturnType.IsValueType) { il.Emit(OpCodes.Unbox_Any, method.ReturnType); } il.Emit(OpCodes.Ret); Type disp = tb.CreateType(); cache[dtype] = disp; return(disp); }
internal override void Apply(ClassLoaderWrapper loader, MethodBuilder mb, object annotation) { }
private void VerifyAddMethodsResult(PropertyInfo myProperty, MethodBuilder expectedMethod) { MethodInfo[] actualMethods = myProperty.GetAccessors(true); Assert.Equal(1, actualMethods.Length); Assert.Equal(expectedMethod.Name, actualMethods[0].Name); }
internal override void Apply(ClassLoaderWrapper loader, MethodBuilder mb, object annotation) { if (type.IsSubclassOf(Types.SecurityAttribute)) { #if STATIC_COMPILER mb.__AddDeclarativeSecurity(MakeCustomAttributeBuilder(loader, annotation)); #elif STUB_GENERATOR #else SecurityAction action; PermissionSet permSet; if (MakeDeclSecurity(type, annotation, out action, out permSet)) { mb.AddDeclarativeSecurity(action, permSet); } #endif } else { mb.SetCustomAttribute(MakeCustomAttributeBuilder(loader, annotation)); } }
static void Main(string[] args) { string name1 = "EmitTest.DynamicFibonacci"; string name2 = "EmitTest.EntityBuilder"; #region Step 1 构建程序集 //创建程序集名 AssemblyName asmName = new AssemblyName(name2); //获取程序集所在的应用程序域 //你也可以选择用AppDomain.CreateDomain方法创建一个新的应用程序域 //这里选择当前的应用程序域 AppDomain domain = AppDomain.CurrentDomain; //实例化一个AssemblyBuilder对象来实现动态程序集的构建 AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); #endregion #region Step 2 定义模块 ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(asmName.Name, asmName.Name + ".dll"); #endregion #region Step 3 定义类型 TypeBuilder typeBuilder = moduleBuilder.DefineType(name2, TypeAttributes.Public); #endregion #region Step 4 定义方法 /* * public class Fibonacci * { * public int Calc(int num) * { * if (num == 1 || num == 2) * { * return 1; * } * else * { * return Calc(num - 1) + Calc(num - 2); * } * } * } * * * MethodBuilder methodBuilder = typeBuilder.DefineMethod( * "Calc", * MethodAttributes.Public, * typeof(Int32), * new Type[] { typeof(Int32) }); * #endregion * #region Step 5 实现方法 * * ILGenerator calcIL = methodBuilder.GetILGenerator(); * * //定义标签lbReturn1,用来设置返回值为1 * Label lbReturn1 = calcIL.DefineLabel(); * //定义标签lbReturnResutl,用来返回最终结果 * Label lbReturnResutl = calcIL.DefineLabel(); * * //加载参数1,和整数1,相比较,如果相等则设置返回值为1 * calcIL.Emit(OpCodes.Ldarg_1); * calcIL.Emit(OpCodes.Ldc_I4_1); * calcIL.Emit(OpCodes.Beq_S, lbReturn1); * * //加载参数1,和整数2,相比较,如果相等则设置返回值为1 * calcIL.Emit(OpCodes.Ldarg_1); * calcIL.Emit(OpCodes.Ldc_I4_2); * calcIL.Emit(OpCodes.Beq_S, lbReturn1); * * //加载参数0和1,将参数1减去1,递归调用自身 * calcIL.Emit(OpCodes.Ldarg_0); * calcIL.Emit(OpCodes.Ldarg_1); * calcIL.Emit(OpCodes.Ldc_I4_1); * calcIL.Emit(OpCodes.Sub); * calcIL.Emit(OpCodes.Call, methodBuilder); * * //加载参数0和1,将参数1减去2,递归调用自身 * calcIL.Emit(OpCodes.Ldarg_0); * calcIL.Emit(OpCodes.Ldarg_1); * calcIL.Emit(OpCodes.Ldc_I4_2); * calcIL.Emit(OpCodes.Sub); * calcIL.Emit(OpCodes.Call, methodBuilder); * * //将递归调用的结果相加,并返回 * calcIL.Emit(OpCodes.Add); * calcIL.Emit(OpCodes.Br, lbReturnResutl); * * //在这里创建标签lbReturn1 * calcIL.MarkLabel(lbReturn1); * calcIL.Emit(OpCodes.Ldc_I4_1); * * //在这里创建标签lbReturnResutl * calcIL.MarkLabel(lbReturnResutl); * calcIL.Emit(OpCodes.Ret); * * * */ #endregion MethodBuilder methodBuilder = typeBuilder.DefineMethod("DynamicCreateEntity", MethodAttributes.Public); var gpas = methodBuilder.DefineGenericParameters("T"); //设置T的约束s gpas[0].SetGenericParameterAttributes(GenericParameterAttributes.ReferenceTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint); //定义参数类型:(IDataRecord dr) methodBuilder.SetParameters(typeof(System.Data.IDataRecord)); //定义返回值类型:T methodBuilder.SetReturnType(gpas[0]); MethodInfo Activator_CreateInstance = typeof(Activator).GetMethod("CreateInstance", Type.EmptyTypes).MakeGenericMethod(gpas[0]); MethodInfo Type_GetProperty = typeof(Type).GetMethod("GetProperty", new Type[] { typeof(string) }); MethodInfo Object_GetType = typeof(object).GetMethod("GetType"); MethodInfo PropertyInfo_Get_PropertyType = typeof(PropertyInfo).GetMethod("get_PropertyType"); MethodInfo PropertyInfo_SetValue = typeof(PropertyInfo).GetMethod("SetValue", new Type[] { typeof(object), typeof(object), typeof(object[]) }); MethodInfo IDataRecord_GetOrdinal = typeof(System.Data.IDataRecord).GetMethod("GetOrdinal", new Type[] { typeof(string) }); MethodInfo IDataRecord_IsDBNull = typeof(System.Data.IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) }); MethodInfo IDataRecord_GetValue = typeof(System.Data.IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) }); MethodInfo IDataRecord_Get_FieldCount = typeof(System.Data.IDataRecord).GetMethod("get_FieldCount"); MethodInfo IDataRecord_GetName = typeof(System.Data.IDataRecord).GetMethod("GetName", new Type[] { typeof(int) }); ILGenerator ilgen = methodBuilder.GetILGenerator(); LocalBuilder result = ilgen.DeclareLocal(gpas[0]); //ilgen.Emit(OpCodes.Newobj, gpas[0].GetConstructor(Type.EmptyTypes)); ilgen.Emit(OpCodes.Call, Activator_CreateInstance); ilgen.Emit(OpCodes.Stloc, result); //循环中使用的局部变量 LocalBuilder i = ilgen.DeclareLocal(typeof(Int32)); Label compareLabel = ilgen.DefineLabel(); Label enterLoopLabel = ilgen.DefineLabel(); LocalBuilder propertyInfo = ilgen.DeclareLocal(typeof(PropertyInfo)); //int i = 0 ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Stloc_1); ilgen.Emit(OpCodes.Br, compareLabel); //定义一个标签,表示从下面开始进入循环体 ilgen.MarkLabel(enterLoopLabel); ilgen.Emit(OpCodes.Ldloc, result); ilgen.Emit(OpCodes.Callvirt, Object_GetType); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldloc, i); ilgen.Emit(OpCodes.Callvirt, IDataRecord_GetName); ilgen.Emit(OpCodes.Callvirt, Type_GetProperty); ilgen.Emit(OpCodes.Stloc, propertyInfo); Label endIfLabel = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldloc, i); ilgen.Emit(OpCodes.Callvirt, IDataRecord_IsDBNull); ilgen.Emit(OpCodes.Brtrue, endIfLabel); ilgen.Emit(OpCodes.Ldloc, propertyInfo); ilgen.Emit(OpCodes.Ldloc, result); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldloc, i); ilgen.Emit(OpCodes.Callvirt, IDataRecord_GetValue); //ilgen.Emit(OpCodes.Callvirt, PropertyInfo_Get_PropertyType); //ilgen.Emit(OpCodes.Unbox_Any); ilgen.Emit(OpCodes.Ldnull); ilgen.Emit(OpCodes.Callvirt, PropertyInfo_SetValue); ilgen.MarkLabel(endIfLabel); //i++ ilgen.Emit(OpCodes.Ldloc_S, i); ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Add); ilgen.Emit(OpCodes.Stloc_S, i); //定义一个标签,表示从下面开始进入循环的比较 ilgen.MarkLabel(compareLabel); //i < ints.Length ilgen.Emit(OpCodes.Ldloc_S, i); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Callvirt, IDataRecord_Get_FieldCount); ilgen.Emit(OpCodes.Conv_I4); ilgen.Emit(OpCodes.Clt); ilgen.Emit(OpCodes.Brtrue_S, enterLoopLabel); ilgen.Emit(OpCodes.Ldloc, result); ilgen.Emit(OpCodes.Ret); #region Step 6 收获 Type type = typeBuilder.CreateType(); assemblyBuilder.Save(asmName.Name + ".dll"); DataTable dt = new DataTable("user"); dt.Columns.Add("UserID", typeof(int)); dt.Columns.Add("UserName", typeof(string)); dt.Rows.Add(new object[] { 1, "f**k" }); dt.Rows.Add(new object[] { 2, "you" }); User user = new Program().DynamicCreateEntity <User>(dt.CreateDataReader()); //object obj = Activator.CreateInstance(type); //MethodInfo method = type.GetMethod("DynamicCreateEntity", new Type[]{ typeof(IDataRecord)}); //method = method.MakeGenericMethod(typeof(User)); //User user = method.Invoke(obj, new object[] { dt.CreateDataReader() }) as User; Console.WriteLine(user.UserID); Console.WriteLine(user.UserName); Console.ReadLine(); //object ob = Activator.CreateInstance(type); //for (int i = 1; i < 10; i++) //{ // Console.WriteLine(type.GetMethod("Calc").Invoke(ob, new object[] { i })); //} //Console.ReadLine(); #endregion }
internal static CodeEmitter Create(MethodBuilder mb) { return new CodeEmitter(mb.GetILGenerator(), mb.DeclaringType); }
/// <summary> /// Emits a C# Assembly with classes whos public properties match the columns of the DataTable. /// </summary> /// <returns>The C# Type for the emitted class</returns> public static Type ToAssembly(DataTable dataTable) { string typeName = dataTable.TableName; string moduleName = string.Format("{0}Module", typeName); string assemblyName = string.Format("{0}Assembly", typeName); AssemblyName asmName = new AssemblyName(assemblyName); AssemblyBuilderAccess accessModes = AssemblyBuilderAccess.RunAndSave; AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, accessModes); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName, string.Format("{0}.mod", moduleName), true); TypeAttributes typeAttributes = TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.AnsiClass | TypeAttributes.AutoClass; TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes); foreach (DataColumn column in dataTable.Columns) { string propertyName = column.ColumnName; Type propertyType = column.DataType; PropertyBuilder propertyBuilder = typeBuilder.DefineProperty( propertyName, System.Reflection.PropertyAttributes.HasDefault, propertyType, null ); // This is the private backing member for the property FieldBuilder fieldPropBacker = typeBuilder.DefineField( "_" + propertyName.ToLower(), propertyType, FieldAttributes.Private ); // The property set and property get methods require a special set of attributes. MethodAttributes accessorAttributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // 2182 int attrVal = (int)accessorAttributes; // 2182 // Define the get accessor method MethodBuilder getAccessor = typeBuilder.DefineMethod( "get_" + propertyName, accessorAttributes, propertyType, Type.EmptyTypes ); ILGenerator getIL = getAccessor.GetILGenerator(); getIL.Emit(OpCodes.Ldarg_0); getIL.Emit(OpCodes.Ldfld, fieldPropBacker); getIL.Emit(OpCodes.Ret); // Define the set accessor method MethodBuilder setAccessor = typeBuilder.DefineMethod( "set_" + propertyName, accessorAttributes, null, new Type[] { propertyType } ); ILGenerator setIL = setAccessor.GetILGenerator(); setIL.Emit(OpCodes.Ldarg_0); setIL.Emit(OpCodes.Ldarg_1); setIL.Emit(OpCodes.Stfld, fieldPropBacker); setIL.Emit(OpCodes.Ret); // Set the getter and the setter propertyBuilder.SetGetMethod(getAccessor); propertyBuilder.SetSetMethod(setAccessor); } Type result = typeBuilder.CreateType(); // Save the assembly assemblyBuilder.Save(assemblyName + ".dll"); return(result); }
public static object ExecuteAsync( object apiController, object controllerContext, object boxedCancellationToken, int opCode, int mdToken, long moduleVersionPtr) { if (apiController == null) { throw new ArgumentNullException(nameof(apiController)); } var cancellationToken = (CancellationToken)boxedCancellationToken; var callOpCode = (OpCodeValue)opCode; var httpControllerType = apiController.GetInstrumentedInterface(HttpControllerTypeName); Type taskResultType; try { var request = controllerContext.GetProperty <object>("Request").GetValueOrDefault(); var httpRequestMessageType = request.GetInstrumentedType("System.Net.Http.HttpRequestMessage"); // The request should never be null, so get the base type found in System.Net.Http.dll if (httpRequestMessageType != null) { var systemNetHttpAssembly = httpRequestMessageType.Assembly; taskResultType = systemNetHttpAssembly.GetType("System.Net.Http.HttpResponseMessage", true); } // This should never happen, but put in a reasonable fallback of finding the first System.Net.Http.dll in the AppDomain else { Log.Warning($"{nameof(AspNetWebApi2Integration)}.{nameof(ExecuteAsync)}: Unable to find System.Net.Http.HttpResponseMessage Type from method arguments. Using fallback logic to find the Type needed for return type."); var statsd = Tracer.Instance.Statsd; if (statsd != null) { statsd.AppendWarning(source: $"{nameof(AspNetWebApi2Integration)}.{nameof(ExecuteAsync)}", message: "Unable to find System.Net.Http.HttpResponseMessage Type from method arguments. Using fallback logic to find the Type needed for return type.", null); statsd.Send(); } var systemNetHttpAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(assembly => assembly.GetName().Name.Equals("System.Net.Http", StringComparison.OrdinalIgnoreCase)); var firstSystemNetHttpAssembly = systemNetHttpAssemblies.First(); taskResultType = firstSystemNetHttpAssembly.GetType("System.Net.Http.HttpResponseMessage", true); } } catch (Exception ex) { // This shouldn't happen because the System.Net.Http assembly should have been loaded if this method was called // The profiled app will not continue working as expected without this method Log.Error(ex, "Error finding types in the user System.Net.Http assembly."); throw; } Func <object, object, CancellationToken, object> instrumentedMethod = null; try { instrumentedMethod = MethodBuilder <Func <object, object, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, nameof(ExecuteAsync)) .WithConcreteType(httpControllerType) .WithParameters(controllerContext, cancellationToken) .WithNamespaceAndNameFilters( ClrNames.GenericTask, HttpControllerContextTypeName, ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: HttpControllerTypeName, methodName: nameof(ExecuteAsync), instanceType: apiController.GetType().AssemblyQualifiedName); throw; } return(AsyncHelper.InvokeGenericTaskDelegate( owningType: apiController.GetType(), taskResultType: taskResultType, nameOfIntegrationMethod: nameof(ExecuteAsyncInternal), integrationType: typeof(AspNetWebApi2Integration), instrumentedMethod, apiController, controllerContext, cancellationToken)); }
private static Type Create(string className, Dictionary <string, Type> properties) { var domain = AppDomain.CurrentDomain; var assemblyName = new AssemblyName(); assemblyName.Name = "TempAssembly.dll"; var assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); var typeBuilder = moduleBuilder.DefineType(className, TypeAttributes.Public | TypeAttributes.Class, typeof(object), new Type[] { typeof(ITypeData) }); // GetPropertiesを実装. var getPropsMethod = typeBuilder.DefineMethod("GetProperties", MethodAttributes.Public | MethodAttributes.Virtual, typeof(string[]), Type.EmptyTypes); var getPropsIL = getPropsMethod.GetILGenerator(); getPropsIL.DeclareLocal(typeof(string[])); LoadInteger(getPropsIL, properties.Count); getPropsIL.Emit(OpCodes.Newarr, typeof(string)); getPropsIL.Emit(OpCodes.Stloc_0); for (var index = 0; index < properties.Count; index++) { getPropsIL.Emit(OpCodes.Ldloc_0); LoadInteger(getPropsIL, index); getPropsIL.Emit(OpCodes.Ldstr, properties.Keys.ElementAt(index)); getPropsIL.Emit(OpCodes.Stelem_Ref); } getPropsIL.Emit(OpCodes.Ldloc_0); getPropsIL.Emit(OpCodes.Ret); var propAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // プロパティを作成. foreach (var Propertie in properties) { // プライベートフィールドの作成. var nameFieldBuilder = typeBuilder.DefineField(Propertie.Key + "_", Propertie.Value, FieldAttributes.Private); // パブリックプロパティ. var namePropertyBuilder = typeBuilder.DefineProperty(Propertie.Key, PropertyAttributes.HasDefault, Propertie.Value, null); //------ Getterメソッドの作成 ------ MethodBuilder getNameMethod = typeBuilder.DefineMethod("get_" + Propertie.Key, propAttr, Propertie.Value, Type.EmptyTypes); ILGenerator getNamePropIL = getNameMethod.GetILGenerator(); getNamePropIL.Emit(OpCodes.Ldarg_0); getNamePropIL.Emit(OpCodes.Ldfld, nameFieldBuilder); getNamePropIL.Emit(OpCodes.Ret); namePropertyBuilder.SetGetMethod(getNameMethod); //------ Setterメソッドの作成 ------ var setNameMethod = typeBuilder.DefineMethod("set_" + Propertie.Key, propAttr, null, new Type[] { Propertie.Value }); ILGenerator setNamePropIL = setNameMethod.GetILGenerator(); setNamePropIL.Emit(OpCodes.Ldarg_0); setNamePropIL.Emit(OpCodes.Ldarg_1); setNamePropIL.Emit(OpCodes.Stfld, nameFieldBuilder); setNamePropIL.Emit(OpCodes.Ret); namePropertyBuilder.SetSetMethod(setNameMethod); } return(typeBuilder.CreateType()); }
public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa) { base.ApplyAttributes (mb, cb, index, pa); pa.ParamArray.EmitAttribute (builder); }
static void DefineCtors(TypeBuilder proxyTB, Type superClass, string initName, string postInitName, ISeq ctorsTypes, FieldBuilder initFB, FieldBuilder postInitFB, FieldBuilder stateFB, string factoryName) { for (ISeq s = ctorsTypes; s != null; s = s.next()) { IMapEntry me = (IMapEntry)s.first(); ISeq thisParamTypesV = (ISeq)me.key(); ISeq baseParamTypesV = (ISeq)me.val(); Type[] thisParamTypes = CreateTypeArray(thisParamTypesV); Type[] baseParamTypes = CreateTypeArray(baseParamTypesV); BindingFlags flags = BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; ConstructorInfo superCtor = superClass.GetConstructor(flags, null, baseParamTypes, null); if (superCtor == null || superCtor.IsPrivate) { throw new InvalidOperationException("Base class constructor missing or private"); } ConstructorBuilder cb = proxyTB.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, thisParamTypes); ILGen gen = new ILGen(cb.GetILGenerator()); Label noInitLabel = gen.DefineLabel(); Label noPostInitLabel = gen.DefineLabel(); Label endPostInitLabel = gen.DefineLabel(); Label endLabel = gen.DefineLabel(); LocalBuilder locSuperArgs = gen.DeclareLocal(typeof(object)); LocalBuilder locInitVal = gen.DeclareLocal(typeof(object)); if (initFB != null) { // init supplied EmitGetVar(gen, initFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, noInitLabel); gen.Emit(OpCodes.Castclass, typeof(IFn)); // box init args for (int i = 0; i < thisParamTypes.Length; i++) { gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (thisParamTypes[i].IsValueType) { gen.Emit(OpCodes.Box, thisParamTypes[i]); } } gen.EmitCall(Compiler.Methods_IFn_invoke[thisParamTypes.Length]); // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[thisParamTypes.Length]); // Expecting: [[super-ctor-args...] state] // store the init return in a local gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Stloc, locInitVal); // store the first element in a local gen.EmitInt(0); // gen.Emit(OpCodes.Ldc_I4_0); gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth); gen.Emit(OpCodes.Stloc, locSuperArgs); // Stack this + super-ctor-args + call base-class ctor. gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < baseParamTypes.Length; i++) { gen.Emit(OpCodes.Ldloc, locSuperArgs); gen.EmitInt(i); // gen.Emit(OpCodes.Ldc_I4, i); gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth); if (baseParamTypes[i].IsValueType) { gen.Emit(OpCodes.Unbox_Any, baseParamTypes[i]); } else { gen.Emit(OpCodes.Castclass, baseParamTypes[i]); } } gen.Emit(OpCodes.Call, superCtor); if (stateFB != null) { gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldloc, locInitVal); gen.EmitInt(1); // gen.Emit(OpCodes.Ldc_I4_1); gen.EmitCall(Method_RT_nth); // gen.Emit(OpCodes.Call, Method_RT_nth); gen.Emit(OpCodes.Castclass, typeof(object)); gen.EmitFieldSet(stateFB); // gen.Emit(OpCodes.Stfld, stateFB); } gen.Emit(OpCodes.Br_S, endLabel); // No init found gen.MarkLabel(noInitLabel); gen.Emit(OpCodes.Pop); EmitUnsupported(gen, initName); gen.MarkLabel(endLabel); } else // no InitFB supplied. { bool ok = thisParamTypes.Length == baseParamTypes.Length; for (int i = 0; ok && i < thisParamTypes.Length; i++) { ok = baseParamTypes[i].IsAssignableFrom(thisParamTypes[i]); } if (!ok) { throw new InvalidOperationException(":init not specified, but ctor and super ctor args differ"); } gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < thisParamTypes.Length; i++) { gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (baseParamTypes[i] != thisParamTypes[i]) { gen.Emit(OpCodes.Castclass, baseParamTypes[i]); } } gen.Emit(OpCodes.Call, superCtor); } if (postInitFB != null) { // post-init supplied EmitGetVar(gen, postInitFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, noPostInitLabel); gen.Emit(OpCodes.Castclass, typeof(IFn)); // box init args gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < thisParamTypes.Length; i++) { gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (thisParamTypes[i].IsValueType) { gen.Emit(OpCodes.Box, thisParamTypes[i]); } gen.Emit(OpCodes.Castclass, thisParamTypes[i]); } gen.EmitCall(Compiler.Methods_IFn_invoke[thisParamTypes.Length + 1]); // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[thisParamTypes.Length + 1]); gen.Emit(OpCodes.Pop); gen.Emit(OpCodes.Br_S, endPostInitLabel); // no post-init found gen.MarkLabel(noPostInitLabel); gen.Emit(OpCodes.Pop); EmitUnsupported(gen, postInitName + " not defined"); gen.MarkLabel(endPostInitLabel); } gen.Emit(OpCodes.Ret); if (!String.IsNullOrEmpty(factoryName)) { MethodBuilder factoryMB = proxyTB.DefineMethod(factoryName, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, proxyTB, thisParamTypes); ILGen genf = new ILGen(factoryMB.GetILGenerator()); LocalBuilder[] locals = new LocalBuilder[thisParamTypes.Length]; for (int i = 0; i < thisParamTypes.Length; i++) { locals[i] = genf.DeclareLocal(thisParamTypes[i]); genf.EmitLoadArg(i); // genf.Emit(OpCodes.Ldarg, i); genf.Emit(OpCodes.Stloc, locals[i]); } for (int i = 0; i < thisParamTypes.Length; i++) { genf.EmitLoadArg(i); // genf.Emit(OpCodes.Ldarg, i); } genf.EmitNew(cb); // genf.Emit(OpCodes.Newobj, cb); genf.Emit(OpCodes.Ret); } } }
/// <summary></summary> public void CompileToMethod(MethodBuilder method) { Predicate.CompileToMethod(method); }
private static void EmitForwardingMethod(TypeBuilder proxyTB, bool isStatic, FieldBuilder regularFB, FieldBuilder overloadFB, MethodSignature sig, ElseGenDelegate elseGen) { MethodAttributes attributes; CallingConventions conventions; if (isStatic) { attributes = MethodAttributes.Public | MethodAttributes.Static; conventions = CallingConventions.Standard; } else { attributes = MethodAttributes.Public | MethodAttributes.Virtual; conventions = CallingConventions.HasThis; } MethodBuilder mb = proxyTB.DefineMethod(sig.Name, attributes, conventions, sig.ReturnType, sig.ParamTypes); ILGen gen = new ILGen(mb.GetILGenerator()); Label foundLabel = gen.DefineLabel(); Label elseLabel = gen.DefineLabel(); Label endLabel = gen.DefineLabel(); if (sig.ParamTypes.Length > 18) { elseGen(gen); } else { if (overloadFB != null) { EmitGetVar(gen, overloadFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brtrue_S, foundLabel); gen.Emit(OpCodes.Pop); } EmitGetVar(gen, regularFB); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Brfalse_S, elseLabel); if (overloadFB != null) { gen.MarkLabel(foundLabel); } gen.Emit(OpCodes.Castclass, typeof(IFn)); if (!isStatic) { gen.EmitLoadArg(0); // gen.Emit(OpCodes.Ldarg_0); } for (int i = 0; i < sig.ParamTypes.Length; i++) { gen.EmitLoadArg(i + 1); // gen.Emit(OpCodes.Ldarg, i + 1); if (sig.ParamTypes[i].IsValueType) { gen.Emit(OpCodes.Box, sig.ParamTypes[i]); } } gen.EmitCall(Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]); //gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[sig.ParamTypes.Length + (isStatic ? 0 : 1)]); if (sig.ReturnType == typeof(void)) { gen.Emit(OpCodes.Pop); } else if (sig.ReturnType.IsValueType) { gen.Emit(OpCodes.Unbox_Any, sig.ReturnType); } gen.Emit(OpCodes.Br_S, endLabel); gen.MarkLabel(elseLabel); gen.Emit(OpCodes.Pop); elseGen(gen); gen.MarkLabel(endLabel); gen.Emit(OpCodes.Ret); } }
/// <summary></summary> public void CompileToMethod(MethodBuilder method, DebugInfoGenerator debugInfoGenerator) { Predicate.CompileToMethod(method, debugInfoGenerator); }
private static void EmitExposers(TypeBuilder proxyTB, Type superClass, IPersistentMap exposesFields) { for (ISeq s = RT.seq(exposesFields); s != null; s = s.next()) { IMapEntry me = (IMapEntry)s.first(); Symbol protectedFieldSym = (Symbol)me.key(); IPersistentMap accessMap = (IPersistentMap)me.val(); string fieldName = protectedFieldSym.Name; Symbol getterSym = (Symbol)accessMap.valAt(_getKw, null); Symbol setterSym = (Symbol)accessMap.valAt(_setKW, null); FieldInfo fld = null; if (getterSym != null || setterSym != null) { fld = superClass.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance); } if (getterSym != null) { MethodAttributes attribs = MethodAttributes.Public; if (fld.IsStatic) { attribs |= MethodAttributes.Static; } MethodBuilder mb = proxyTB.DefineMethod(getterSym.Name, attribs, fld.FieldType, Type.EmptyTypes); ILGen gen = new ILGen(mb.GetILGenerator()); //if (fld.IsStatic) // gen.Emit(OpCodes.Ldsfld, fld); //else //{ // gen.Emit(OpCodes.Ldarg_0); // gen.Emit(OpCodes.Ldfld, fld); //} if (!fld.IsStatic) { gen.EmitLoadArg(0); } gen.EmitFieldGet(fld); gen.Emit(OpCodes.Ret); } if (setterSym != null) { MethodAttributes attribs = MethodAttributes.Public; if (fld.IsStatic) { attribs |= MethodAttributes.Static; } MethodBuilder mb = proxyTB.DefineMethod(setterSym.Name, attribs, typeof(void), new Type[] { fld.FieldType }); ILGen gen = new ILGen(mb.GetILGenerator()); if (fld.IsStatic) { gen.Emit(OpCodes.Ldarg_0); //gen.Emit(OpCodes.Stsfld, fld); } else { gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); //gen.Emit(OpCodes.Stfld, fld); } gen.EmitFieldSet(fld); gen.Emit(OpCodes.Ret); } } }
public MethodBuilderBundle(BuilderBundle bundle, MethodBuilder builder) { this.builder = builder; ModuleBuilder = bundle.ModuleBuilder; }
public static object HttpClientHandler_Send( object handler, object request, object boxedCancellationToken, int opCode, int mdToken, long moduleVersionPtr) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } // original signature: // HttpResponseMessage HttpClientHandler.Send(HttpRequestMessage request, CancellationToken cancellationToken) var cancellationToken = (CancellationToken)boxedCancellationToken; var callOpCode = (OpCodeValue)opCode; var httpClientHandler = handler.GetInstrumentedType(SystemNetHttp, HttpClientHandlerTypeName); Func <object, object, CancellationToken, object> instrumentedMethod = null; try { instrumentedMethod = MethodBuilder <Func <object, object, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, Send) .WithConcreteType(httpClientHandler) .WithParameters(request, cancellationToken) .WithNamespaceAndNameFilters(ClrNames.HttpResponseMessage, ClrNames.HttpRequestMessage, ClrNames.CancellationToken) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: HttpClientHandler, methodName: Send, instanceType: handler.GetType().AssemblyQualifiedName); throw; } var requestValue = request.DuckCast <HttpRequestMessageStruct>(); var reportedType = callOpCode == OpCodeValue.Call ? httpClientHandler : handler.GetType(); if (!IsTracingEnabled(requestValue.Headers)) { // skip instrumentation return(instrumentedMethod(handler, request, cancellationToken)); } return(SendInternal( instrumentedMethod, reportedType, requestValue, handler, request, cancellationToken)); }
internal override void ApplyReturnValue(ClassLoaderWrapper loader, MethodBuilder mb, ref ParameterBuilder pb, object annotation) { // TODO make sure the descriptor is correct Annotation ann = type.Annotation; object[] arr = (object[])annotation; for (int i = 2; i < arr.Length; i += 2) { if ("value".Equals(arr[i])) { if (pb == null) { pb = mb.DefineParameter(0, ParameterAttributes.None, null); } object[] value = (object[])arr[i + 1]; if (value[0].Equals(AnnotationDefaultAttribute.TAG_ANNOTATION)) { ann.Apply(loader, pb, value); } else { for (int j = 1; j < value.Length; j++) { ann.Apply(loader, pb, value[j]); } } break; } } }
public static object HttpMessageHandler_SendAsync( object handler, object request, object boxedCancellationToken, int opCode, int mdToken, long moduleVersionPtr) { if (handler == null) { throw new ArgumentNullException(nameof(handler)); } // original signature: // Task<HttpResponseMessage> HttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) var cancellationToken = (CancellationToken)boxedCancellationToken; var callOpCode = (OpCodeValue)opCode; var httpMessageHandler = handler.GetInstrumentedType(SystemNetHttp, HttpMessageHandlerTypeName); Func <object, object, CancellationToken, object> instrumentedMethod = null; try { instrumentedMethod = MethodBuilder <Func <object, object, CancellationToken, object> > .Start(moduleVersionPtr, mdToken, opCode, SendAsync) .WithConcreteType(httpMessageHandler) .WithParameters(request, cancellationToken) .WithNamespaceAndNameFilters(NamespaceAndNameFilters) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: HttpMessageHandler, methodName: SendAsync, instanceType: handler.GetType().AssemblyQualifiedName); throw; } var reportedType = callOpCode == OpCodeValue.Call ? httpMessageHandler : handler.GetType(); var requestValue = request.DuckCast <HttpRequestMessageStruct>(); var isHttpClientHandler = handler.GetInstrumentedType(SystemNetHttp, HttpClientHandlerTypeName) != null; if (!(isHttpClientHandler || IsSocketsHttpHandlerEnabled(reportedType)) || !IsTracingEnabled(requestValue.Headers)) { // skip instrumentation return(instrumentedMethod(handler, request, cancellationToken)); } Type taskResultType = _httpMessageHandlerResultType; if (taskResultType == null || taskResultType.Assembly != httpMessageHandler.Assembly) { try { var currentHttpAssembly = httpMessageHandler.Assembly; taskResultType = currentHttpAssembly.GetType("System.Net.Http.HttpResponseMessage", true); _httpMessageHandlerResultType = taskResultType; } catch (Exception ex) { // This shouldn't happen because the System.Net.Http assembly should have been loaded if this method was called // profiled app will not continue working as expected without this method Log.Error(ex, "Error finding types in the user System.Net.Http assembly."); throw; } } return(SendAsyncInternal( instrumentedMethod, reportedType, requestValue, handler, request, cancellationToken) .Cast(taskResultType)); }
internal override void Apply(ClassLoaderWrapper loader, MethodBuilder mb, object annotation) { Annotation annot = type.Annotation; foreach (object ann in UnwrapArray(annotation)) { annot.Apply(loader, mb, ann); } }
public static void CreateAsm(AppDomain currAppDomain) { //общие характеристики сборки AssemblyName assemblyName = new AssemblyName();//new AssemblyName("MyAssemblyName") assemblyName.Name = "MyAssembly"; assemblyName.Version = new Version("1.0.0.0"); //создать новую сборку внутри текущего домена приложения AssemblyBuilder assembly = currAppDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save); //Поскольку сборка однофайловая, то имя модуля будет таким же, как и у сборки ModuleBuilder module = assembly.DefineDynamicModule("MyAssembly", "MyAssembly.dll"); //Определить закрытую переменную-член типа String по имени HelloWorld. TypeBuilder HelloWorldClass = module.DefineType("MyAssembly.HelloWorld", TypeAttributes.Public); //Определить закрытую переменную - член класса FieldBuilder msgField = HelloWorldClass.DefineField("theMessage", Type.GetType("System.String"), FieldAttributes.Private); //Создать специальный конструктор Type[] constructorArgs = new Type[1]; constructorArgs[0] = typeof(String); ConstructorBuilder constructor = HelloWorldClass.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArgs); ILGenerator constructorIL = constructor.GetILGenerator(); constructorIL.Emit(OpCodes.Ldarg_0); Type objectClass = typeof(object); ConstructorInfo constructorInfo = objectClass.GetConstructor(new Type[0]); constructorIL.Emit(OpCodes.Call, constructorInfo); constructorIL.Emit(OpCodes.Ldarg_0); constructorIL.Emit(OpCodes.Ldarg_1); constructorIL.Emit(OpCodes.Stfld, msgField); constructorIL.Emit(OpCodes.Ret); //Создать стандартный конструктор HelloWorldClass.DefineDefaultConstructor(MethodAttributes.Public); //Создать метод msg MethodBuilder methodMsg = HelloWorldClass.DefineMethod("GetMessage", MethodAttributes.Public, typeof(string), null); ILGenerator methodGenerator = methodMsg.GetILGenerator(); methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.Emit(OpCodes.Ldfld, msgField); methodGenerator.Emit(OpCodes.Ret); //Создать метод SayHello() MethodBuilder methodSayHello = HelloWorldClass.DefineMethod("SayHello", MethodAttributes.Public, null, null); ILGenerator sayHiGenerator = methodSayHello.GetILGenerator(); sayHiGenerator.EmitWriteLine("Hello from say hello method"); sayHiGenerator.Emit(OpCodes.Ret); //Выпустить класс HelloWorld HelloWorldClass.CreateType(); //Сохранение динамической сборки в файл assembly.Save("MyAssembly.dll"); }
internal static CodeEmitter Create(MethodBuilder mb) { return new CodeEmitter(mb.GetILGenerator()); }
public MethodData (InterfaceMemberBase member, Modifiers modifiers, MethodAttributes flags, IMethodData method, MethodBuilder builder, MethodSpec parent_method) : this (member, modifiers, flags, method) { this.builder = builder; this.parent_method = parent_method; }
internal void EmitLineNumberTable(MethodBuilder mb) { if(linenums != null) { AttributeHelper.SetLineNumberTable(mb, linenums); } }
public override bool Define () { if (!base.Define ()) return false; if (!CheckBase ()) return false; MemberKind kind; if (this is Operator) kind = MemberKind.Operator; else if (this is Destructor) kind = MemberKind.Destructor; else kind = MemberKind.Method; if (IsPartialDefinition) { caching_flags &= ~Flags.Excluded_Undetected; caching_flags |= Flags.Excluded; // Add to member cache only when a partial method implementation has not been found yet if ((caching_flags & Flags.PartialDefinitionExists) == 0) { // MethodBase mb = new PartialMethodDefinitionInfo (this); spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags); if (MemberName.Arity > 0) { spec.IsGeneric = true; // TODO: Have to move DefineMethod after Define (ideally to Emit) throw new NotImplementedException ("Generic partial methods"); } Parent.MemberCache.AddMember (spec); } return true; } MethodData = new MethodData ( this, ModFlags, flags, this, MethodBuilder, base_method); if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName))) return false; MethodBuilder = MethodData.MethodBuilder; spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags); if (MemberName.Arity > 0) spec.IsGeneric = true; Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec); return true; }
public SerializerPair(int metaKey, int baseKey, MetaType type, MethodBuilder serialize, MethodBuilder deserialize, ILGenerator serializeBody, ILGenerator deserializeBody) { this.MetaKey = metaKey; this.BaseKey = baseKey; this.Serialize = serialize; this.Deserialize = deserialize; this.SerializeBody = serializeBody; this.DeserializeBody = deserializeBody; this.Type = type; }
void enterLambdaMethod(MethodBuilder methodBuilder) { context.MemberResolver.enterMethod(methodBuilder, true); methods.add(methodBuilder); returnTypes.add(new ArrayList<TypeInfo>()); }
/// <summary> /// Generate the method emiting IL Code /// </summary> /// <param name="m">External method info</param> /// <param name="typeBuilder">TypeBuilder needed to generate proxy type using IL code</param> private static void EmitProxyMethod(MethodInfo m, TypeBuilder typeBuilder) { Type[] paramTypes = Helper.GetParameterTypes(m); MethodBuilder mb = typeBuilder.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.Virtual, m.ReturnType, paramTypes); ILGenerator il = mb.GetILGenerator(); LocalBuilder parameters = il.DeclareLocal(typeof(object[])); il.Emit(OpCodes.Ldc_I4, paramTypes.Length); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, parameters); for (int i = 0; i < paramTypes.Length; i++) { il.Emit(OpCodes.Ldloc, parameters); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldarg, i + 1); if (paramTypes[i].IsValueType) { il.Emit(OpCodes.Box, paramTypes[i]); } il.Emit(OpCodes.Stelem_Ref); } il.EmitCall(OpCodes.Call, typeof(CodeInjection).GetProperty("InjectHandler").GetGetMethod(), null); // Parameter 1 object targetObject il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, (FieldInfo)_target); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, (FieldInfo)_target); il.EmitCall(OpCodes.Call, typeof(object).GetMethod("GetType"), null); il.EmitCall(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod"), null); //Parameter 2 MethodBase method il.EmitCall(OpCodes.Call, typeof(Helper).GetMethod("GetMethodFromType"), null); //Parameter 3 object[] parameters il.Emit(OpCodes.Ldloc, parameters); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, (FieldInfo)_interface); il.EmitCall(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod"), null); il.EmitCall(OpCodes.Call, typeof(Helper).GetMethod("GetMethodFromType"), null); il.Emit(OpCodes.Ldtoken, typeof(AspectAttribute)); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Ldc_I4, 1); il.EmitCall(OpCodes.Callvirt, typeof(MethodInfo).GetMethod("GetCustomAttributes", new Type[] { typeof(Type), typeof(bool) }), null); //Parameter 4 AspectAttribute[] aspects il.EmitCall(OpCodes.Call, typeof(Helper).GetMethod("AspectUnion"), null); il.EmitCall(OpCodes.Call, typeof(MethodCall).GetMethod("Invoke"), null); if (m.ReturnType == typeof(void)) { il.Emit(OpCodes.Pop); } else if (m.ReturnType.IsValueType) { il.Emit(OpCodes.Unbox, m.ReturnType); il.Emit(OpCodes.Ldind_Ref); } il.Emit(OpCodes.Ret); }
public override object Copy(object objSrc) { IMapperEmit m = null; if (emitter != null) { return(emitter.Copy(objSrc)); } TypeBuilder tBuilder = GetTypeBuilder("Property"); MethodBuilder mBuilder = GetMethodBuilder(tBuilder); FieldBuilder fb = tBuilder.DefineField( "target", typeof(IMapperEmit), FieldAttributes.Private); ConstructorBuilder cb = tBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.ExplicitThis, new Type[] { typeof(IMapperEmit) }); /*********************************** IL CODE ***************************/ ILGenerator cbIlGen = cb.GetILGenerator(); cbIlGen.Emit(OpCodes.Ldarg_0); cbIlGen.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); cbIlGen.Emit(OpCodes.Ldarg_0); cbIlGen.Emit(OpCodes.Ldarg_1); cbIlGen.Emit(OpCodes.Stfld, fb); cbIlGen.Emit(OpCodes.Ret); ILGenerator ilGenerator = mBuilder.GetILGenerator(); LocalBuilder localSrc = ilGenerator.DeclareLocal(src); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Castclass, src); ilGenerator.Emit(OpCodes.Stloc, localSrc); ilGenerator.Emit(OpCodes.Newobj, dest.GetConstructors()[0]); foreach (KeyValuePair <PropertyInfo, PropertyInfo> pair in propertyList) { if (pair.Key.PropertyType.IsAssignableFrom(pair.Value.PropertyType)) { ilGenerator.Emit(OpCodes.Dup); ilGenerator.Emit(OpCodes.Ldloc, localSrc); ilGenerator.Emit(OpCodes.Callvirt, pair.Key.GetGetMethod()); ilGenerator.Emit(OpCodes.Callvirt, pair.Value.GetSetMethod()); } else { if (map.TryGetValue(pair, out m)) { ilGenerator.Emit(OpCodes.Dup); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, fb); ilGenerator.Emit(OpCodes.Ldloc, localSrc); ilGenerator.Emit(OpCodes.Callvirt, pair.Key.GetGetMethod()); ilGenerator.Emit(OpCodes.Callvirt, typeof(IMapperEmit).GetMethod("Map", new [] { typeof(object) })); ilGenerator.Emit(OpCodes.Callvirt, pair.Value.GetSetMethod()); } } } ilGenerator.Emit(OpCodes.Ret); Type t = tBuilder.CreateType(); asm.Save(tBuilder.Name + ".dll"); emitter = (IEmitter)Activator.CreateInstance(t, m); return(emitter.Copy(objSrc)); }
/// <summary> /// Create the MethodBuilder for the method /// </summary> void DefineMethodBuilder (TypeDefinition container, string method_name, ParametersCompiled param) { var return_type = method.ReturnType.GetMetaInfo (); var p_types = param.GetMetaInfo (); if (builder == null) { builder = container.TypeBuilder.DefineMethod ( method_name, flags, method.CallingConventions, return_type, p_types); return; } // // Generic method has been already defined to resolve method parameters // correctly when they use type parameters // builder.SetParameters (p_types); builder.SetReturnType (return_type); if (builder.Attributes != flags) { #if STATIC builder.__SetAttributes (flags); #else try { if (methodbuilder_attrs_field == null) methodbuilder_attrs_field = typeof (MethodBuilder).GetField ("attrs", BindingFlags.NonPublic | BindingFlags.Instance); methodbuilder_attrs_field.SetValue (builder, flags); } catch { container.Compiler.Report.RuntimeMissingSupport (method.Location, "Generic method MethodAttributes"); } #endif } }
static void Main() { string name = "InMemory"; AssemblyBuilder asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(name), AssemblyBuilderAccess.Run); ModuleBuilder modBldr = asmBldr.DefineDynamicModule(name); TypeBuilder tb = modBldr.DefineType("DemoVararg"); // Create a vararg method with no return value and one // string argument. (The string argument type is the only // element of an array of Type objects.) // MethodBuilder mb1 = tb.DefineMethod("VarargMethod", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.VarArgs, null, new Type[] { typeof(string) }); ILGenerator il1 = mb1.GetILGenerator(); LocalBuilder locAi = il1.DeclareLocal(typeof(ArgIterator)); LocalBuilder locNext = il1.DeclareLocal(typeof(bool)); Label labelCheckCondition = il1.DefineLabel(); Label labelNext = il1.DefineLabel(); // Load the fixed argument and print it. il1.Emit(OpCodes.Ldarg_0); il1.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(string) })); // Load the address of the local variable represented by // locAi, which will hold the ArgIterator. il1.Emit(OpCodes.Ldloca_S, locAi); // Load the address of the argument list, and call the // ArgIterator constructor that takes an array of runtime // argument handles. il1.Emit(OpCodes.Arglist); il1.Emit(OpCodes.Call, typeof(ArgIterator).GetConstructor(new Type[] { typeof(RuntimeArgumentHandle) })); // Enter the loop at the point where the remaining argument // count is tested. il1.Emit(OpCodes.Br_S, labelCheckCondition); // At the top of the loop, call GetNextArg to get the next // argument from the ArgIterator. Convert the typed reference // to an object reference and write the object to the console. il1.MarkLabel(labelNext); il1.Emit(OpCodes.Ldloca_S, locAi); il1.Emit(OpCodes.Call, typeof(ArgIterator).GetMethod("GetNextArg", Type.EmptyTypes)); il1.Emit(OpCodes.Call, typeof(TypedReference).GetMethod("ToObject")); il1.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(object) })); il1.MarkLabel(labelCheckCondition); il1.Emit(OpCodes.Ldloca_S, locAi); il1.Emit(OpCodes.Call, typeof(ArgIterator).GetMethod("GetRemainingCount")); // If the remaining count is greater than zero, go to // the top of the loop. il1.Emit(OpCodes.Ldc_I4_0); il1.Emit(OpCodes.Cgt); il1.Emit(OpCodes.Stloc_1); il1.Emit(OpCodes.Ldloc_1); il1.Emit(OpCodes.Brtrue_S, labelNext); il1.Emit(OpCodes.Ret); // Create a method that contains a call to the vararg // method. MethodBuilder mb2 = tb.DefineMethod("CallVarargMethod", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), Type.EmptyTypes); ILGenerator il2 = mb2.GetILGenerator(); // Push arguments on the stack: one for the fixed string // parameter, and two for the list. il2.Emit(OpCodes.Ldstr, "Hello "); il2.Emit(OpCodes.Ldstr, "world "); il2.Emit(OpCodes.Ldc_I4, 2006); // Call the vararg method, specifying the types of the // arguments in the list. il2.EmitCall(OpCodes.Call, mb1, new Type[] { typeof(string), typeof(int) }); il2.Emit(OpCodes.Ret); Type type = tb.CreateType(); type.GetMethod("CallVarargMethod").Invoke(null, null); }
void enterMethod(MethodBuilder methodBuilder) { context.MemberResolver.enterMethod(methodBuilder); this.IsStatic = methodBuilder.IsStatic; methods.add(methodBuilder); this.YieldCount = 0; }
// 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 TypeInfo of the generated attribute. private TypeInfo GenerateTypeInfoOfIgnoresAccessChecksToAttribute() { 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 getterPropertyBuilder = 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); // 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().Count() == 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()); }
void initialize(MethodBuilder methodBuilder, TypeBuilder lambdaScope) { this.methods.clear(); this.ParametersUsedInLambdas.clear(); this.ParametersUsedInLambda.clear(); this.CatchVariables.clear(); this.TreeLocals.clear(); this.TreeLabels.clear(); this.LocalFields.clear(); this.Labels.clear(); this.methods.add(methodBuilder); this.LambdaScope = lambdaScope; this.Generator = methodBuilder.CodeGenerator; this.destructor = methodBuilder.Name.equals("finalize") && !methodBuilder.Parameters.any(); this.IsLambdaScopeUsed = false; this.IsLambdaScopeInitialized = false; this.IsLambdaScopeThisInitialized = false; this.IsBuildingString = false; this.foreachStatement = 0; this.YieldCount = 0; this.stringSwitch = 0; this.PreviousLineNumber = 0; this.generatedLocal = 0; }
private void AddMethodImpl(MethodInfo mi) { ParameterInfo[] parameters = mi.GetParameters(); Type[] paramTypes = ParamTypes(parameters, false); MethodBuilder mdb = _tb.DefineMethod(mi.Name, MethodAttributes.Public | MethodAttributes.Virtual, mi.ReturnType, paramTypes); if (mi.ContainsGenericParameters) { Type[] ts = mi.GetGenericArguments(); string[] ss = new string[ts.Length]; for (int i = 0; i < ts.Length; i++) { ss[i] = ts[i].Name; } GenericTypeParameterBuilder[] genericParameters = mdb.DefineGenericParameters(ss); for (int i = 0; i < genericParameters.Length; i++) { genericParameters[i].SetGenericParameterAttributes(ts[i].GetTypeInfo().GenericParameterAttributes); } } ILGenerator il = mdb.GetILGenerator(); ParametersArray args = new ParametersArray(il, paramTypes); // object[] args = new object[paramCount]; il.Emit(OpCodes.Nop); GenericArray <object> argsArr = new GenericArray <object>(il, ParamTypes(parameters, true).Length); for (int i = 0; i < parameters.Length; i++) { // args[i] = argi; if (!parameters[i].IsOut) { argsArr.BeginSet(i); args.Get(i); argsArr.EndSet(parameters[i].ParameterType); } } // object[] packed = new object[PackedArgs.PackedTypes.Length]; GenericArray <object> packedArr = new GenericArray <object>(il, PackedArgs.PackedTypes.Length); // packed[PackedArgs.DispatchProxyPosition] = this; packedArr.BeginSet(PackedArgs.DispatchProxyPosition); il.Emit(OpCodes.Ldarg_0); packedArr.EndSet(typeof(DispatchProxy)); // packed[PackedArgs.DeclaringTypePosition] = typeof(iface); MethodInfo Type_GetTypeFromHandle = typeof(Type).GetRuntimeMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) }); int methodToken; Type declaringType; _assembly.GetTokenForMethod(mi, out declaringType, out methodToken); packedArr.BeginSet(PackedArgs.DeclaringTypePosition); il.Emit(OpCodes.Ldtoken, declaringType); il.Emit(OpCodes.Call, Type_GetTypeFromHandle); packedArr.EndSet(typeof(object)); // packed[PackedArgs.MethodTokenPosition] = iface method token; packedArr.BeginSet(PackedArgs.MethodTokenPosition); il.Emit(OpCodes.Ldc_I4, methodToken); packedArr.EndSet(typeof(Int32)); // packed[PackedArgs.ArgsPosition] = args; packedArr.BeginSet(PackedArgs.ArgsPosition); argsArr.Load(); packedArr.EndSet(typeof(object[])); // packed[PackedArgs.GenericTypesPosition] = mi.GetGenericArguments(); if (mi.ContainsGenericParameters) { packedArr.BeginSet(PackedArgs.GenericTypesPosition); Type[] genericTypes = mi.GetGenericArguments(); GenericArray <Type> typeArr = new GenericArray <Type>(il, genericTypes.Length); for (int i = 0; i < genericTypes.Length; ++i) { typeArr.BeginSet(i); il.Emit(OpCodes.Ldtoken, genericTypes[i]); il.Emit(OpCodes.Call, Type_GetTypeFromHandle); typeArr.EndSet(typeof(Type)); } typeArr.Load(); packedArr.EndSet(typeof(Type[])); } // Call static DispatchProxyHelper.Invoke(object[]) il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, _fields[InvokeActionFieldAndCtorParameterIndex]); // delegate packedArr.Load(); il.Emit(OpCodes.Call, s_delegateInvoke); for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.IsByRef) { args.BeginSet(i); argsArr.Get(i); args.EndSet(i, typeof(object)); } } if (mi.ReturnType != typeof(void)) { packedArr.Get(PackedArgs.ReturnValuePosition); Convert(il, typeof(object), mi.ReturnType, false); } il.Emit(OpCodes.Ret); _tb.DefineMethodOverride(mdb, mi); }
// // Creates partial MethodBuilder for the method when has generic parameters used // as arguments or return type // public MethodBuilder DefineMethodBuilder (TypeDefinition container) { if (builder != null) throw new InternalErrorException (); builder = container.TypeBuilder.DefineMethod (full_name, flags, method.CallingConventions); return builder; }
private static TypeAccessor CreateNew(Type type, bool allowNonPublicAccessors) { #if !NO_DYNAMIC if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type)) { return(DynamicAccessor.Singleton); } #endif PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance); Dictionary <string, int> map = new Dictionary <string, int>(); List <MemberInfo> members = new List <MemberInfo>(props.Length + fields.Length); int i = 0; foreach (var prop in props) { if (!map.ContainsKey(prop.Name) && prop.GetIndexParameters().Length == 0) { map.Add(prop.Name, i++); members.Add(prop); } } foreach (var field in fields) { if (!map.ContainsKey(field.Name)) { map.Add(field.Name, i++); members.Add(field); } } ConstructorInfo ctor = null; if (_IsClass(type) && !_IsAbstract(type)) { ctor = type.GetConstructor(TypeHelpers.EmptyTypes); } ILGenerator il; if (!IsFullyPublic(type, props, allowNonPublicAccessors)) { DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(int), typeof(object) }, type, true), dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(int), typeof(object), typeof(object) }, type, true); WriteMapImpl(dynGetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, true); WriteMapImpl(dynSetter.GetILGenerator(), type, members, null, allowNonPublicAccessors, false); DynamicMethod dynCtor = null; if (ctor != null) { dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), TypeHelpers.EmptyTypes, type, true); il = dynCtor.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); } return(new DelegateAccessor( map, (Func <int, object, object>)dynGetter.CreateDelegate(typeof(Func <int, object, object>)), (Action <int, object, object>)dynSetter.CreateDelegate(typeof(Action <int, object, object>)), dynCtor == null ? null : (Func <object>)dynCtor.CreateDelegate(typeof(Func <object>)), type)); } // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders if (assembly == null) { AssemblyName name = new AssemblyName("FastMember_dynamic"); #if COREFX assembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); #else assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run); #endif module = assembly.DefineDynamicModule(name.Name); } #if COREFX TypeAttributes attribs = typeof(TypeAccessor).GetTypeInfo().Attributes; #else TypeAttributes attribs = typeof(TypeAccessor).Attributes; #endif TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + GetNextCounterValue(), (attribs | TypeAttributes.Sealed | TypeAttributes.Public) & ~(TypeAttributes.Abstract | TypeAttributes.NotPublic), typeof(RuntimeTypeAccessor)); il = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(Dictionary <string, int>) }).GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); FieldBuilder mapField = tb.DefineField("_map", typeof(Dictionary <string, int>), FieldAttributes.InitOnly | FieldAttributes.Private); il.Emit(OpCodes.Stfld, mapField); il.Emit(OpCodes.Ret); PropertyInfo indexer = typeof(TypeAccessor).GetProperty("Item"); MethodInfo baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod(); MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) }); il = body.GetILGenerator(); WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, true); tb.DefineMethodOverride(body, baseGetter); body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) }); il = body.GetILGenerator(); WriteMapImpl(il, type, members, mapField, allowNonPublicAccessors, false); tb.DefineMethodOverride(body, baseSetter); MethodInfo baseMethod; if (ctor != null) { baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod(); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, TypeHelpers.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); baseMethod = typeof(TypeAccessor).GetMethod("CreateNew"); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, TypeHelpers.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); } baseMethod = typeof(RuntimeTypeAccessor).GetProperty("Type", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true); body = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.ReturnType, TypeHelpers.EmptyTypes); il = body.GetILGenerator(); il.Emit(OpCodes.Ldtoken, type); il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle")); il.Emit(OpCodes.Ret); tb.DefineMethodOverride(body, baseMethod); var accessor = (TypeAccessor)Activator.CreateInstance(_CreateType(tb), map); return(accessor); }
public override void ApplyAttributes (MethodBuilder mb, ConstructorBuilder cb, int index, PredefinedAttributes pa) { // Nothing to do }
public static object BeginInvokeAction( object asyncControllerActionInvoker, object controllerContext, object actionName, object callback, object state, int opCode, int mdToken, long moduleVersionPtr) { if (asyncControllerActionInvoker == null) { throw new ArgumentNullException(nameof(asyncControllerActionInvoker)); } Scope scope = null; try { if (HttpContext.Current != null) { scope = CreateScope(controllerContext); HttpContext.Current.Items[HttpContextKey] = scope; } } catch (Exception ex) { Log.Error(ex, "Error instrumenting method {0}", "System.Web.Mvc.Async.IAsyncActionInvoker.BeginInvokeAction()"); } Func<object, object, object, object, object, object> instrumentedMethod; try { var asyncActionInvokerType = asyncControllerActionInvoker.GetInstrumentedInterface(AsyncActionInvokerTypeName); instrumentedMethod = MethodBuilder<Func<object, object, object, object, object, object>> .Start(moduleVersionPtr, mdToken, opCode, nameof(BeginInvokeAction)) .WithConcreteType(asyncActionInvokerType) .WithParameters(controllerContext, actionName, callback, state) .WithNamespaceAndNameFilters( ClrNames.IAsyncResult, "System.Web.Mvc.ControllerContext", ClrNames.String, ClrNames.AsyncCallback, ClrNames.Object) .Build(); } catch (Exception ex) { Log.ErrorRetrievingMethod( exception: ex, moduleVersionPointer: moduleVersionPtr, mdToken: mdToken, opCode: opCode, instrumentedType: AsyncActionInvokerTypeName, methodName: nameof(BeginInvokeAction), instanceType: asyncControllerActionInvoker.GetType().AssemblyQualifiedName); throw; } try { // call the original method, inspecting (but not catching) any unhandled exceptions return instrumentedMethod(asyncControllerActionInvoker, controllerContext, actionName, callback, state); } catch (Exception ex) { scope?.Span.SetException(ex); throw; } }
/// <summary> /// 创建 TCP 客户端 /// </summary> /// <param name="type"></param> /// <param name="attribute"></param> /// <param name="methods"></param> /// <param name="getCommandMethod"></param> /// <returns></returns> internal Type Build(Type type, ServerBaseAttribute attribute, Method <attributeType, methodAttributeType, serverSocketSenderType>[] methods, MethodInfo getCommandMethod) { TypeBuilder typeBuilder = AutoCSer.Emit.Builder.Module.Builder.DefineType(Metadata.ClientTypeName + ".Emit." + type.FullName, TypeAttributes.Class | TypeAttributes.Sealed, Metadata.MethodClientType, new Type[] { type }); typeBuilder.DefineDefaultConstructor(MethodAttributes.Public); ConstructorBuilder staticConstructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null); ILGenerator staticConstructorGenerator = staticConstructorBuilder.GetILGenerator(); Commands = new CommandInfo[methods.Length]; int parameterIndex; foreach (Method <attributeType, methodAttributeType, serverSocketSenderType> nextMethod in methods) { if (nextMethod != null) { Method <attributeType, methodAttributeType, serverSocketSenderType> method = nextMethod; METHOD: FieldBuilder commandInfoFieldBuilder; if (method.Attribute.IsExpired) { commandInfoFieldBuilder = null; } else { commandInfoFieldBuilder = typeBuilder.DefineField("_c" + method.Attribute.CommandIdentity.toString(), typeof(CommandInfo), FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static); CommandInfo commandInfo = new CommandInfo { Command = method.Attribute.CommandIdentity + TcpServer.Server.CommandStartIndex, TaskType = method.IsAsynchronousCallback ? method.Attribute.ClientTaskType : AutoCSer.Net.TcpServer.ClientTaskType.Synchronous, IsVerifyMethod = method.Attribute.IsVerifyMethod }; Commands[method.Attribute.CommandIdentity] = commandInfo; if (method.IsClientSendOnly) { commandInfo.IsSendOnly = 1; } if (method.IsJsonSerialize) { commandInfo.CommandFlags = CommandFlags.JsonSerialize; } if (method.ParameterType != null) { commandInfo.InputParameterIndex = method.ParameterType.Index; if (attribute.IsSimpleSerialize) { commandInfo.IsSimpleSerializeInputParamter = method.ParameterType.IsSimpleSerialize; } } if (attribute.IsSimpleSerialize && method.OutputParameterType != null) { commandInfo.IsSimpleSerializeOutputParamter = method.OutputParameterType.IsSimpleSerialize && SimpleSerialize.Serializer.IsType(method.ReturnType); } #region private static readonly AutoCSer.Net.TcpServer.CommandInfo @MethodIdentityCommand = AutoCSer.Net.TcpInternalServer.Emit.Client<interfaceType>.commands[method.Attribute.CommandIdentity]; staticConstructorGenerator.int32(method.Attribute.CommandIdentity); staticConstructorGenerator.call(getCommandMethod); staticConstructorGenerator.Emit(OpCodes.Stsfld, commandInfoFieldBuilder); #endregion } if (method.PropertyInfo == null) { ParameterInfo[] parameters = method.MethodInfo.GetParameters(); MethodBuilder methodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType)); typeBuilder.DefineMethodOverride(methodBuilder, method.MethodInfo); ILGenerator methodGenerator = methodBuilder.GetILGenerator(); if (method.Attribute.IsExpired) { if (method.ReturnValueType == null) { #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString()); methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString()); #endregion } else { #region @ParameterName = default(@ParameterType.FullName); parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.IsOut) { methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.VersionExpired }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj())) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired); methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } else if (method.IsClientSendOnly) { LocalBuilder inputParameterLocalBuilder; if (method.ParameterType == null) { inputParameterLocalBuilder = null; } else { #region TcpInternalServer.@InputParameterTypeName _inputParameter_ = new TcpInternalServer.@InputParameterTypeName { @ParameterName = @ParameterName }; inputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); LocalBuilder newInputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, newInputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type); } parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (StreamParameterType.IsInputParameter(parameter)) { methodGenerator.parameterToStructField(parameter, parameterIndex, newInputParameterLocalBuilder, method.ParameterType.GetField(parameter.Name)); } } methodGenerator.Emit(OpCodes.Ldloc_S, newInputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Stloc_S, inputParameterLocalBuilder); #endregion } #region _TcpClient_.Sender.CallOnly(@MethodIdentityCommand, ref _inputParameter_); methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.call(Metadata.MethodClientGetTcpClientMethod); methodGenerator.call(Metadata.ClientGetSenderMethod); methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder); if (method.ParameterType == null) { methodGenerator.call(Metadata.ClientSocketSenderCallOnlyMethod); } else { methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder); methodGenerator.call(Metadata.ClientSocketSenderCallOnlyInputMethod.MakeGenericMethod(method.ParameterType.Type)); } #endregion methodGenerator.Emit(OpCodes.Ret); } else { Label clientExceptionLabel = methodGenerator.DefineLabel(), returnLable = methodGenerator.DefineLabel(), returnReturnValueLable, returnValueLable; LocalBuilder returnReturnValueLocalBuilder, returnValueLocalBuilder; if (method.ReturnValueType == null) { returnReturnValueLocalBuilder = null; returnReturnValueLable = default(Label); } else { returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); returnReturnValueLable = methodGenerator.DefineLabel(); } if (method.ReturnValueType == null && method.ReturnType != typeof(void)) { returnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnType); returnValueLable = methodGenerator.DefineLabel(); } else { returnValueLocalBuilder = null; returnValueLable = default(Label); } #region AutoCSer.Net.TcpServer.AutoWaitReturnValue<TcpInternalServer.@OutputParameterTypeName> _wait_ = _TcpClient_.GetAutoWait<TcpInternalServer.@OutputParameterTypeName>(); Type waitType = method.OutputParameterType == null ? typeof(AutoCSer.Net.TcpServer.AutoWaitReturnValue) : typeof(AutoCSer.Net.TcpServer.AutoWaitReturnValue <>).MakeGenericType(method.OutputParameterType.Type); LocalBuilder waitLocalBuilder = methodGenerator.DeclareLocal(waitType); methodGenerator.call(method.OutputParameterType == null ? TcpServer.Emit.ClientMetadata.AutoWaitReturnValuePopMethod : waitType.GetMethod("Pop", BindingFlags.Static | BindingFlags.Public)); methodGenerator.Emit(OpCodes.Stloc_S, waitLocalBuilder); #endregion #region try methodGenerator.BeginExceptionBlock(); #endregion Label leaveTryLabel = methodGenerator.DefineLabel(); LocalBuilder senderLocalBuilder = methodGenerator.DeclareLocal(Metadata.SenderType); parameterIndex = 0; if (method.Attribute.IsVerifyMethod) { foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType == Metadata.SenderType) { #region AutoCSer.Net.TcpInternalServer.ClientSocketSender _socket_ = _sender_; methodGenerator.ldarg(parameterIndex); methodGenerator.Emit(OpCodes.Stloc_S, senderLocalBuilder); #endregion parameterIndex = int.MinValue; break; } } } if (parameterIndex != int.MinValue) { #region AutoCSer.Net.TcpInternalServer.ClientSocketSender _socket_ = _TcpClient_.Sender; methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.call(Metadata.MethodClientGetTcpClientMethod); methodGenerator.call(Metadata.ClientGetSenderMethod); methodGenerator.Emit(OpCodes.Stloc_S, senderLocalBuilder); #endregion } #region if (_socket_ != null) methodGenerator.Emit(OpCodes.Ldloc_S, senderLocalBuilder); methodGenerator.Emit(method.ParameterType == null ? OpCodes.Brfalse_S : OpCodes.Brfalse, leaveTryLabel); #endregion LocalBuilder inputParameterLocalBuilder; if (method.ParameterType == null) { inputParameterLocalBuilder = null; } else { #region TcpInternalServer.@InputParameterTypeName _inputParameter_ = new TcpInternalServer.@InputParameterTypeName { @ParameterName = @ParameterName }; inputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); LocalBuilder newInputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, newInputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type); } parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (StreamParameterType.IsInputParameter(parameter)) { methodGenerator.parameterToStructField(parameter, parameterIndex, newInputParameterLocalBuilder, method.ParameterType.GetField(parameter.Name)); } } methodGenerator.Emit(OpCodes.Ldloc_S, newInputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Stloc_S, inputParameterLocalBuilder); #endregion } if (method.OutputParameterType == null) { #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _socket_.WaitCall(@MethodIdentityCommand, ref _wait_, ref _inputParameter_); LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType)); methodGenerator.Emit(OpCodes.Ldloc_S, senderLocalBuilder); methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, waitLocalBuilder); if (method.ParameterType == null) { methodGenerator.call(Metadata.ClientSocketSenderWaitCallMethod); } else { methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder); methodGenerator.call(Metadata.ClientSocketSenderWaitCallInputMethod.MakeGenericMethod(method.ParameterType.Type)); } methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion if (method.ReturnValueType == null) { Label throwReturnTypeLabel = methodGenerator.DefineLabel(); #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success) return; methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); methodGenerator.Emit(OpCodes.Bne_Un_S, throwReturnTypeLabel); methodGenerator.Emit(OpCodes.Leave_S, returnLable); #endregion methodGenerator.MarkLabel(throwReturnTypeLabel); #region throw new Exception(AutoCSer.Net.TcpInternalServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]); methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Ldelem_Ref); methodGenerator.Emit(OpCodes.Newobj, AutoCSer.Extension.EmitGenerator.StringExceptionConstructor); methodGenerator.Emit(OpCodes.Throw); #endregion } else { #region return new AutoCSer.Net.TcpServer.ReturnValue { Type = _returnType_ }; //methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); //methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Stfld, TcpServer.Emit.ClientMetadata.ReturnValueTypeField); methodGenerator.Emit(OpCodes.Leave, returnReturnValueLable); #endregion } } else { #region TcpInternalServer.@OutputParameterTypeName _outputParameter_ = new TcpInternalServer.@OutputParameterTypeName { @ParameterName = @ParameterName }; LocalBuilder outputParameterLocalBuilder = methodGenerator.DeclareLocal(method.OutputParameterType.Type); if (method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.OutputParameterType.Type); } parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.parameterToStructField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } //if (method.ReturnInputParameter != null) //{ //} #endregion #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _socket_.WaitGet<TcpInternalServer.@InputParameterTypeName, TcpInternalServer.@OutputParameterTypeName>(@MethodIdentityCommand, ref _wait_, ref _inputParameter_, ref _outputParameter_); LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType)); methodGenerator.Emit(OpCodes.Ldloc_S, senderLocalBuilder); methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, waitLocalBuilder); if (method.ParameterType == null) { methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.call(Metadata.ClientSocketSenderWaitGetMethod.MakeGenericMethod(method.OutputParameterType.Type)); } else { methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.call(Metadata.ClientSocketSenderWaitGetInputMethod.MakeGenericMethod(method.ParameterType.Type, method.OutputParameterType.Type)); } methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion if (method.ReturnValueType == null) { Label throwReturnTypeLabel = methodGenerator.DefineLabel(); #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success) methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); methodGenerator.Emit(OpCodes.Bne_Un, throwReturnTypeLabel); #endregion #region @ParameterName = _outputParameter_.@ParameterName; parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } #endregion if (method.ReturnType == typeof(void)) { #region return; methodGenerator.Emit(OpCodes.Leave_S, returnLable); #endregion } else { #region return _outputParameter_.Ret; methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName)); methodGenerator.Emit(OpCodes.Stloc_S, returnValueLocalBuilder); methodGenerator.Emit(OpCodes.Leave_S, returnValueLable); #endregion } methodGenerator.MarkLabel(throwReturnTypeLabel); #region throw new Exception(AutoCSer.Net.TcpServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]); methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Ldelem_Ref); methodGenerator.Emit(OpCodes.Newobj, AutoCSer.Extension.EmitGenerator.StringExceptionConstructor); methodGenerator.Emit(OpCodes.Throw); #endregion } else { #region @ParameterName = _outputParameter_.@ParameterName; parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = _returnType_, Value = _outputParameter_.Return }; if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj())) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); if (method.ReturnType != typeof(void)) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(ReturnValue.RetParameterName)); methodGenerator.Emit(OpCodes.Stfld, method.ReturnValueType.GetField("Value", BindingFlags.Instance | BindingFlags.Public)); } methodGenerator.Emit(OpCodes.Leave, returnReturnValueLable); #endregion } } methodGenerator.MarkLabel(leaveTryLabel); methodGenerator.Emit(OpCodes.Leave_S, clientExceptionLabel); #region finally methodGenerator.BeginFinallyBlock(); #endregion Label endfinallyLabel = methodGenerator.DefineLabel(); #region if (_wait_ != null) methodGenerator.Emit(OpCodes.Ldloc_S, waitLocalBuilder); methodGenerator.Emit(OpCodes.Brfalse_S, endfinallyLabel); #endregion #region AutoCSer.Net.TcpServer.AutoWaitReturnValue<TcpInternalServer.@OutputParameterTypeName>.PushNotNull(_wait_); methodGenerator.Emit(OpCodes.Ldloc_S, waitLocalBuilder); if (method.OutputParameterType == null) { methodGenerator.call(TcpServer.Emit.ClientMetadata.AutoWaitReturnValuePushNotNullMethod); } else { Type autoWaitReturnValueType = typeof(AutoCSer.Net.TcpServer.AutoWaitReturnValue <>).MakeGenericType(method.OutputParameterType.Type); methodGenerator.call(autoWaitReturnValueType.GetMethod(TcpServer.Emit.ClientMetadata.AutoWaitReturnValuePushNotNullMethod.Name, BindingFlags.Static | BindingFlags.Public, null, new Type[] { autoWaitReturnValueType }, null)); } #endregion methodGenerator.MarkLabel(endfinallyLabel); methodGenerator.Emit(OpCodes.Endfinally); #region try end methodGenerator.EndExceptionBlock(); #endregion methodGenerator.MarkLabel(clientExceptionLabel); if (method.ReturnValueType == null) { #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString()); methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString()); #endregion methodGenerator.MarkLabel(returnLable); methodGenerator.Emit(OpCodes.Ret); if (method.ReturnType != typeof(void)) { methodGenerator.MarkLabel(returnValueLable); #region @MethodReturnType.FullName methodGenerator.Emit(OpCodes.Ldloc_S, returnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } else { #region @ParameterName = default(@ParameterType.FullName); parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.IsOut) { methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.ClientException }; if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj())) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ClientException); methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); methodGenerator.MarkLabel(returnReturnValueLable); methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.MarkLabel(returnLable); methodGenerator.Emit(OpCodes.Ret); #endregion } } } else if (method.IsPropertySetMethod) { if (method.PropertyBuilder != null || method.PropertyGetMethod == null) { ParameterInfo[] parameters = method.MethodInfo.GetParameters(); PropertyBuilder propertyBuilder = method.PropertyBuilder ?? typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, parameters[parameters.Length - 1].ParameterType, new LeftArray <ParameterInfo> { Array = parameters, Length = parameters.Length - 1 }.GetArray(parameter => parameter.ParameterType)); MethodBuilder setMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType)); ILGenerator methodGenerator = setMethodBuilder.GetILGenerator(); //XXX propertyBuilder.SetSetMethod(setMethodBuilder); method.PropertyBuilder = null; } } else { Type[] parameterTypes = method.MethodInfo.GetParameters().getArray(parameter => parameter.ParameterType); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, method.MethodInfo.ReturnType, parameterTypes); MethodBuilder getMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameterTypes); ILGenerator methodGenerator = getMethodBuilder.GetILGenerator(); //XXX propertyBuilder.SetGetMethod(getMethodBuilder); if (method.PropertySetMethod != null) { method = method.PropertySetMethod; method.PropertyBuilder = propertyBuilder; goto METHOD; } } } } staticConstructorGenerator.Emit(OpCodes.Ret); return(typeBuilder.CreateType()); }
private static ILogger EmitLogger(Type klass) { AssemblyName aName = new AssemblyName("DynamicLogger" + klass.Name); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly( aName, AssemblyBuilderAccess.RunAndSave); // For a single-module assembly, the module name is usually // the assembly name plus an extension. ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll"); TypeBuilder tb = mb.DefineType( "Logger" + klass.Name, TypeAttributes.Public, typeof(AbstractLogger)); MethodBuilder methodBuilder = tb.DefineMethod( "Log", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.ReuseSlot, typeof(string), // Return Type new Type[] { typeof(object) } // Types of arguments ); ILGenerator il = methodBuilder.GetILGenerator(); FieldInfo[] fs = klass.GetFields( BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); LocalBuilder target = il.DeclareLocal(klass); il.Emit(OpCodes.Ldarg_1); // push target il.Emit(OpCodes.Castclass, klass); // castclass il.Emit(OpCodes.Stloc, target); // store on local variable il.Emit(OpCodes.Ldstr, ""); foreach (FieldInfo p in fs) { object[] attrs = p.GetCustomAttributes(typeof(LoggableAttribute), true); if (attrs.Length == 0) { continue; } il.Emit(OpCodes.Ldstr, p.Name); // push on stack the field name il.Emit(OpCodes.Ldloc, target); // ldloc target il.Emit(OpCodes.Ldfld, p); // ldfld if (p.FieldType.IsValueType) { il.Emit(OpCodes.Box, p.FieldType); // box } if (p.FieldType.IsArray) { il.Emit(OpCodes.Call, formatterForArray); } else { il.Emit(OpCodes.Call, formatterForObject); } il.Emit(OpCodes.Call, concat); } il.Emit(OpCodes.Ret); // ret // Finish the type. Type t = tb.CreateType(); ab.Save(aName.Name + ".dll"); return((ILogger)Activator.CreateInstance(t)); }