private static MethodBuilder DefineMethodInterceptingDelegate(TypeBuilder typeBuilder, MethodInfo overridedMethod, Dictionary <Type, FieldInfo> interceptorFields, MethodInfo genericInterceptionAction, MethodInfo voidInterceptionAction, Type[] genericParameterTypes, MethodBuilder @delegate, int index, Type interceptor) { ConstructorInfo delegateConstructor; MethodInfo interceptorMethod; // Define the method var method = typeBuilder.DefineMethod($"{overridedMethod.Name}-{interceptor.Name}_{index}_Interceptor", MethodAttributes.Private | MethodAttributes.HideBySig, overridedMethod.ReturnType, new[] { typeof(ParamInfo[]) }); SetupGenericMethodArguments(overridedMethod, method); using (var il = new GroboIL(method)) { if (overridedMethod.ReturnType != typeof(void)) { interceptorMethod = genericInterceptionAction.MakeGenericMethod(overridedMethod.ReturnType); delegateConstructor = typeof(TDelegate <>).MakeGenericType(overridedMethod.ReturnType).GetConstructor(new[] { typeof(object), typeof(IntPtr) }); } else { interceptorMethod = voidInterceptionAction; delegateConstructor = typeof(VoidDelegate).GetConstructor(new[] { typeof(object), typeof(IntPtr) }); } il.Ldarg(0); il.Ldfld(interceptorFields[interceptor]); il.Ldarg(0); if (overridedMethod.IsGenericMethodDefinition) { il.Ldftn(@delegate.MakeGenericMethod(genericParameterTypes)); } else { il.Ldftn(@delegate); } il.Newobj(delegateConstructor); il.Ldarg(1); il.Call(interceptorMethod); il.Ret(); @delegate = method; } return(@delegate); }
private Func <TestClassA, int> Build1() { var typeBuilder = Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Class | TypeAttributes.Public); var method = typeBuilder.DefineMethod("zzz", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(TestClassA) }); using (var il = new GroboIL(method)) { il.Ldarg(0); il.Ldfld(typeof(TestClassA).GetField("Y")); var y = il.DeclareLocal(typeof(int)); il.Stloc(y); il.Ldarg(0); il.Ldfld(typeof(TestClassA).GetField("Z")); var z = il.DeclareLocal(typeof(int)); il.Stloc(z); il.Ldloc(y); il.Ldloc(z); il.Add(); il.Ret(); } var type = typeBuilder.CreateType(); var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(Func <TestClassA, int>), Type.EmptyTypes, Module, true); using (var il = new GroboIL(dynamicMethod)) { il.Ldnull(); il.Ldftn(type.GetMethod("zzz")); il.Newobj(typeof(Func <TestClassA, int>).GetConstructor(new[] { typeof(object), typeof(IntPtr) })); il.Ret(); } return(((Func <Func <TestClassA, int> >)dynamicMethod.CreateDelegate(typeof(Func <Func <TestClassA, int> >)))()); }
protected TDelegate CompileToMethod <TDelegate>(Expression <TDelegate> lambda, CompilerOptions options) where TDelegate : class { var typeBuilder = TestPerformance.Module.DefineType(Guid.NewGuid().ToString(), TypeAttributes.Public); var method = typeBuilder.DefineMethod("lambda", MethodAttributes.Public | MethodAttributes.Static, lambda.ReturnType, lambda.Parameters.Select(parameter => parameter.Type).ToArray()); LambdaCompiler.CompileToMethod(lambda, method, options); var type = typeBuilder.CreateType(); var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, typeof(TDelegate), null, TestPerformance.Module, true); using (var il = new GroboIL(dynamicMethod)) { il.Ldnull(); il.Ldftn(type.GetMethod("lambda")); il.Newobj(typeof(TDelegate).GetConstructor(new[] { typeof(object), typeof(IntPtr) })); il.Ret(); } return(((Func <TDelegate>)dynamicMethod.CreateDelegate(typeof(Func <TDelegate>)))()); }