static void TT() { DynamicMethod multiplyHidden = new DynamicMethod( "", typeof(void), new[] { typeof(int) }, typeof(Example)); ILGenerator ig = multiplyHidden.GetILGenerator(); ig.BeginExceptionBlock(); ig.Emit(OpCodes.Call, typeof(A).GetMethod("ThrowMe")); ig.BeginCatchBlock(typeof(Exception)); ig.Emit(OpCodes.Call, typeof(A).GetMethod("Handler")); ig.EndExceptionBlock(); ig.Emit(OpCodes.Ret); var invoke = (Action<int>) multiplyHidden.CreateDelegate( typeof(Action<int>) ); invoke(1); }
public void CreateDynMethod_TypeOwner(bool skipVisibility) { Type[] parameterTypes = new Type[] { typeof(TestClass), typeof(int) }; DynamicMethod method = new DynamicMethod("Method", typeof(int), parameterTypes, typeof(TestClass), skipVisibility); MethodInfo baseDefinition = method.GetBaseDefinition(); Assert.Equal(method, baseDefinition); }
static void M2() { // DynamicMethod wrapper method DynamicMethod dm = new DynamicMethod("MyMethodWrapper", typeof(object), new Type[] { typeof(object[]) }, typeof(Program), true); ILGenerator il = dm.GetILGenerator(); Label l1 = il.DefineLabel(); LocalBuilder returnLocal = il.DeclareLocal(typeof(object)); // grab the method parameters of the method we wish to wrap ParameterInfo[] methodParameters = typeof(Foo).GetMethod("MyMethod").GetParameters(); int parameterLength = methodParameters.Length; MethodInfo method = typeof(Foo).GetMethod("MyMethod"); // check to see if the call to MyMethodWrapper has the required amount of arguments in the object[] array. il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldlen); il.Emit(OpCodes.Conv_I4); il.Emit(OpCodes.Ldc_I4, parameterLength + 1); il.Emit(OpCodes.Beq_S, l1); il.Emit(OpCodes.Ldstr, "insufficient arguments"); il.Emit(OpCodes.Newobj, typeof(System.ArgumentException).GetConstructor(new Type[] { typeof(string) })); il.Emit(OpCodes.Throw); il.MarkLabel(l1); // pull out the Foo instance from the first element in the object[] args array il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ldelem_Ref); // cast the instance to Foo il.Emit(OpCodes.Castclass, typeof(Foo)); // pull out the parameters to the instance method call and push them on to the IL stack for (int i = 0; i < parameterLength; i++) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, i + 1); il.Emit(OpCodes.Ldelem_Ref); // we've special cased it, for this code example if (methodParameters[i].ParameterType == typeof(string)) { il.Emit(OpCodes.Castclass, typeof(string)); } // test or switch on parameter types, you'll need to cast to the respective type // ... } // call the wrapped method il.Emit(OpCodes.Call, method); // return what the method invocation returned il.Emit(OpCodes.Stloc, returnLocal); il.Emit(OpCodes.Ldloc, returnLocal); il.Emit(OpCodes.Ret); TestShowVisualizer(dm); }
public void CreateDynMethod_Module(bool skipVisibility) { Module module = typeof(TestClass).GetTypeInfo().Module; Type[] parameterTypes = new Type[] { typeof(TestClass), typeof(int) }; DynamicMethod method = new DynamicMethod("Method", typeof(int), parameterTypes, module, skipVisibility); MethodInfo baseDefinition = method.GetBaseDefinition(); Assert.Equal(method, baseDefinition); }
static void Main (string [] args) { MethodInfo minfo = typeof (Program).GetMethod ("GetInt"); DynamicMethod method = new DynamicMethod ("GetInt", typeof (object), new Type [] { typeof (object []) }, typeof (Program).Module); // generate the method body ILGenerator generator = method.GetILGenerator (); MethodInfo changetype = typeof (Convert).GetMethod ("ChangeType", new Type [] { typeof (object), typeof (Type), typeof (IFormatProvider) }); MethodInfo gettypefromhandle = typeof (Type).GetMethod ("GetTypeFromHandle", new Type [] { typeof (RuntimeTypeHandle) }); MethodInfo get_InvariantCulture = typeof (CultureInfo).GetMethod ( "get_InvariantCulture", BindingFlags.Static | BindingFlags.Public, null, Type.EmptyTypes, null); // for each parameter of the original method, load it on stack ParameterInfo [] parameters = minfo.GetParameters (); for (int i = 0; i < parameters.Length; i++) { ParameterInfo par = parameters [i]; // load the array generator.Emit (OpCodes.Ldarg, 0); // load the index in the array generator.Emit (OpCodes.Ldc_I4, (int) i); // get the element at given index generator.Emit (OpCodes.Ldelem_Ref); // convert it if necessary if (par.ParameterType.IsPrimitive || par.ParameterType == typeof (string)) { // load the parameter type onto stack generator.Emit (OpCodes.Ldtoken, par.ParameterType); generator.EmitCall (OpCodes.Callvirt, gettypefromhandle, null); // load the invariant culture onto stack generator.EmitCall (OpCodes.Call, get_InvariantCulture, null); // call Convert.ChangeType generator.EmitCall (OpCodes.Call, changetype, null); // if necessary, unbox the value if (par.ParameterType.IsValueType) generator.Emit (OpCodes.Unbox_Any, par.ParameterType); } } generator.EmitCall (OpCodes.Call, minfo, null); if (minfo.ReturnType == typeof (void)) generator.Emit (OpCodes.Ldnull); if (minfo.ReturnType.IsValueType) generator.Emit (OpCodes.Box, minfo.ReturnType); generator.Emit (OpCodes.Ret); BodyDelegate del = (BodyDelegate) method.CreateDelegate ( typeof (BodyDelegate)); Assert.AreEqual (0, del (new object [] { 0 }), "#1"); Assert.AreEqual (5, del (new object [] { 5 }), "#2"); }
static bool DoLdelem () { DynamicMethod dm = new DynamicMethod ("EmittedLdelem", typeof (int), null, typeof (Testcase)); ILGenerator il = dm.GetILGenerator (); il.Emit (OpCodes.Ldsfld, ArrayFI); il.Emit (OpCodes.Ldc_I4_1); il.Emit (OpCodes.Ldelem, typeof (int)); il.Emit (OpCodes.Ret); int i = (int) dm.Invoke (null, null); return (i == 2); }
public static void ILTest () { ConstructorInfo constructor = typeof (ClassWithThrowingConstructor).GetConstructor (Type.EmptyTypes); DynamicMethod dm = new DynamicMethod (String.Empty, typeof (object), new Type [] { typeof (object []) }); ILGenerator il = dm.GetILGenerator (); il.Emit (OpCodes.Newobj, constructor); il.Emit (OpCodes.Ret); MyDelegate md = dm.CreateDelegate (typeof (MyDelegate)) as MyDelegate; md.Invoke (new object [0]); }
static bool DoStelem () { DynamicMethod dm = new DynamicMethod ("EmittedStelem", null, null, typeof (Testcase)); ILGenerator il = dm.GetILGenerator (); il.Emit (OpCodes.Ldsfld, ArrayFI); il.Emit (OpCodes.Ldc_I4_0); il.Emit (OpCodes.Ldc_I4_0); il.Emit (OpCodes.Stelem, typeof (int)); il.Emit (OpCodes.Ret); dm.Invoke (null, null); return (Array [0] == 0); }
static void DoStuff () { DynamicMethod method = new DynamicMethod ("GetField", typeof (int), new Type [0], Type.GetType ("Host")); ILGenerator il = method.GetILGenerator (); il.Emit (OpCodes.Ldsfld, typeof (Host).GetField ("Field", BindingFlags.Static | BindingFlags.NonPublic)); il.Emit (OpCodes.Ret); var g = (Getter)method.CreateDelegate (typeof (Getter)); new Host (g); }
public void CreateDelegate_Type(IDClass target) { int newId = 0; FieldInfo field = typeof(IDClass).GetField(FieldName, BindingFlags.NonPublic | BindingFlags.Instance); DynamicMethod method = new DynamicMethod("Method", typeof(int), new Type[] { typeof(IDClass), typeof(int) }, typeof(IDClass)); ILGenerator ilGenerator = method.GetILGenerator(); Helpers.EmitMethodBody(ilGenerator, field); IDClassDelegate staticCallBack = (IDClassDelegate)method.CreateDelegate(typeof(IDClassDelegate)); Assert.Equal(staticCallBack(target, newId), target.ID); Assert.Equal(newId, target.ID); }
public EmitCalculator(string term, int a, int b, int c, int d) { this.dm = new DynamicMethod( "Evaluate" , typeof(int) , new Type[] {typeof(int),typeof(int),typeof(int),typeof(int),typeof(int)} , typeof(int) ); this.tokens = term.Split(new Char[] {' '}); this.ilGen = dm.GetILGenerator(); this.GenCode(); Evaluate eval = (Evaluate) dm.CreateDelegate(typeof(Evaluate)); Console.WriteLine(eval(a, b, c, d, 0)); }
public static int Main() { DynamicMethod method_builder = new DynamicMethod ("WriteHello" , typeof (int), new Type[] {typeof (Driver)}, typeof (Driver)); ILGenerator ilg = method_builder.GetILGenerator (); ilg.Emit (OpCodes.Ldarg_0); ilg.Emit (OpCodes.Call, typeof (Driver).GetMethod ("Foo")); ilg.Emit (OpCodes.Ret); int res = (int) method_builder.Invoke (null, new object[] {new Driver()}); return res == -99 ? 0 : 1; }
public void ILGenerator_Int_Type(bool skipVisibility) { IDClass target = new IDClass(); FieldInfo field = typeof(IDClass).GetField(FieldName, BindingFlags.Instance | BindingFlags.NonPublic); Type[] paramTypes = new Type[] { typeof(IDClass), typeof(int) }; DynamicMethod method = new DynamicMethod("Method", typeof(int), paramTypes, typeof(IDClass), skipVisibility); ILGenerator ilGenerator = method.GetILGenerator(8); Helpers.EmitMethodBody(ilGenerator, field); IntDelegate instanceCallBack = (IntDelegate)method.CreateDelegate(typeof(IntDelegate), target); VerifyILGenerator(instanceCallBack, target, 0); }
public static int Main() { DynamicMethod method_builder = new DynamicMethod ("ThrowException" , typeof (void), new Type[0], typeof (Driver)); ILGenerator ilg = method_builder.GetILGenerator (); ilg.Emit (OpCodes.Newobj, typeof (MyException).GetConstructor (new Type[0])); ilg.Emit (OpCodes.Throw); try { method_builder.Invoke (null, null); return 2; } catch (TargetInvocationException tie) { if(! (tie.InnerException is MyException)) return 3; } return 0; }
static DynamicMethod EmitDynamicMethod(MethodInfo callee) { DynamicMethod method = new DynamicMethod( "MyMethod", typeof(void), new Type[0], typeof(My).GetTypeInfo().Module); ILGenerator il = method.GetILGenerator(); for (int i = 0; i < 5; i++) il.Emit(OpCodes.Call, callee); il.Emit(OpCodes.Ret); return method; }
static void M1() { DynamicMethod dm = new DynamicMethod("HelloWorld", typeof(void), new Type[] { }, typeof(Program), false); ILGenerator il = dm.GetILGenerator(); TestShowVisualizer(dm); il.Emit(OpCodes.Ldstr, "hello, world"); TestShowVisualizer(dm); il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); TestShowVisualizer(dm); il.Emit(OpCodes.Ret); TestShowVisualizer(dm); dm.Invoke(null, null); }
static int Main (string [] args) { DynamicMethod method = new DynamicMethod ("GetInt", typeof (int), Type.EmptyTypes, typeof (Program).Module); ILGenerator generator = method.GetILGenerator (); MethodInfo parse = typeof (Int32).GetMethod ("Parse", new Type [] { typeof (string) }); generator.Emit (OpCodes.Ldstr, "555"); generator.EmitCall (OpCodes.Callvirt, parse, null); generator.Emit (OpCodes.Ret); BodyDelegate del = (BodyDelegate) method.CreateDelegate (typeof (BodyDelegate)); return (del () == 555) ? 0 : 1; }
public void CreateDelegate_Target_Module(IDClass target) { Module module = typeof(TestClass).GetTypeInfo().Module; int newId = 0; FieldInfo field = typeof(IDClass).GetField(FieldName, BindingFlags.NonPublic | BindingFlags.Instance); DynamicMethod method = new DynamicMethod("Method", typeof(int), new Type[] { typeof(IDClass), typeof(int) }, module, true); ILGenerator ilGenerator = method.GetILGenerator(); Helpers.EmitMethodBody(ilGenerator, field); IntDelegate instanceCallBack = (IntDelegate)method.CreateDelegate(typeof(IntDelegate), target); Assert.Equal(instanceCallBack(newId), target.ID); Assert.Equal(newId, target.ID); }
public void TestMethod1() { DynamicMethod dynamicMethod = new DynamicMethod(typeof(object), new[] { typeof(object[]), typeof(object) }); var generator = dynamicMethod.GetILGenerator(); var constructor = typeof(Foo).GetConstructor(Type.EmptyTypes); generator.Emit(OpCodes.Newobj, constructor); var func = (Func<object[], object>)dynamicMethod.CreateDelegate(typeof(Func<object[], object>)); var instance = func(null); Assert.IsInstanceOfType(instance, typeof(Foo)); }
private static int Main() { DynamicMethod method = new DynamicMethod("GetField", typeof(string), new Type[0], typeof(Host)); ILGenerator il = method.GetILGenerator(); il.Emit(OpCodes.Ldsfld, typeof(Host).GetField( "s_field", BindingFlags.Static | BindingFlags.NonPublic)); il.Emit(OpCodes.Ret); Getter g = (Getter)method.CreateDelegate(typeof(Getter)); string res = g(); return Assert(res == "somefield", "Host has not been properly initialized"); }
public void String_Type_TypeArray_Type(string name, Type returnType, Type[] parameterTypes, Type owner) { DynamicMethod method1 = new DynamicMethod(name, returnType, parameterTypes, owner); Helpers.VerifyMethod(method1, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner.GetTypeInfo().Module); DynamicMethod method2 = new DynamicMethod(name, returnType, parameterTypes, owner, true); Helpers.VerifyMethod(method2, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner.GetTypeInfo().Module); DynamicMethod method3 = new DynamicMethod(name, returnType, parameterTypes, owner, false); Helpers.VerifyMethod(method3, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner.GetTypeInfo().Module); DynamicMethod method4 = new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, true); Helpers.VerifyMethod(method4, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner.GetTypeInfo().Module); DynamicMethod method5 = new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner, false); Helpers.VerifyMethod(method5, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, owner.GetTypeInfo().Module); }
public static int Main () { DynamicMethod method = new DynamicMethod ("GetField", typeof (int), new Type [0], Type.GetType ("Host")); ILGenerator il = method.GetILGenerator (); il.Emit (OpCodes.Ldsfld, typeof (Host).GetField ( "Field", BindingFlags.Static | BindingFlags.NonPublic)); il.Emit (OpCodes.Ret); Getter g = (Getter) method.CreateDelegate (typeof (Getter)); Console.WriteLine (g ()); if (g () == 42) return 0; return 1; }
public void DynamicMethodTest3() { var f = new int[,] { {0, 1, 2, 4, 8, 9, 9, 23}, {0, 2, 4, 6, 6, 8, 10, 11}, {0, 3, 4, 7, 7, 8, 8, 24} }; int c = f.GetLength(1) - 1; var expectedResult = new int[] { 0, 0, 7 }; var gm = new DynamicMethod(f, c); var actualResult = gm.Solve(); Assert.AreEqual(24, gm.ResultCost); Assert.AreEqual(expectedResult, actualResult); }
public void DynamicMethodTest2() { var f = new int[,] { {0, 1, 1, 3, 6, 10, 11}, {0, 2, 3, 5, 6, 7, 13}, {0, 1, 4, 4, 7, 8, 9} }; int c = f.GetLength(1) - 1; var expectedResult = new int[] { 0, 6, 0 }; var gm = new DynamicMethod(f, c); var actualResult = gm.Solve(); Assert.AreEqual(13, gm.ResultCost); Assert.AreEqual(expectedResult, actualResult); }
public void DynamicMethodTest1() { var f = new int[,] { {0, 1, 2, 2, 4, 5, 6}, {0, 2, 3, 5, 7, 7, 8}, {0, 2, 4, 5, 6, 7, 7} }; int c = f.GetLength(1) - 1; var expectedResult = new int[] { 0, 4, 2 }; var gm = new DynamicMethod(f, c); var actualResult = gm.Solve(); Assert.AreEqual(11, gm.ResultCost); Assert.AreEqual(expectedResult, actualResult); }
public void DynamicMethodTest() { var f = new int[,] { {0, 3, 4, 5, 8, 9, 10}, {0, 2, 3, 7, 9, 12, 13}, {0, 1, 2, 6, 11, 11, 13} }; int c = f.GetLength(1) - 1; var expectedResult = new int[] { 1, 1, 4 }; var gm = new DynamicMethod(f, c); var actualResult = gm.Solve(); Assert.AreEqual(16, gm.ResultCost); Assert.AreEqual(expectedResult, actualResult); }
public void String_Type_TypeArray_Module(string name, Type returnType, Type[] parameterTypes) { Module module = typeof(TestClass).GetTypeInfo().Module; DynamicMethod method1 = new DynamicMethod(name, returnType, parameterTypes, module); Helpers.VerifyMethod(method1, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, module); DynamicMethod method2 = new DynamicMethod(name, returnType, parameterTypes, module, true); Helpers.VerifyMethod(method2, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, module); DynamicMethod method3 = new DynamicMethod(name, returnType, parameterTypes, module, false); Helpers.VerifyMethod(method3, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, module); DynamicMethod method4 = new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, module, true); Helpers.VerifyMethod(method4, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, module); DynamicMethod method5 = new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, module, false); Helpers.VerifyMethod(method5, name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, parameterTypes, module); }
static void Main () { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture; DynamicMethod method = new DynamicMethod("func", typeof(void), new Type[0], typeof(Program)); ILGenerator ilgen = method.GetILGenerator(); try { ilgen.Emit (OpCodes.Ldftn, method); Assert.Fail ("#A1"); } catch (ArgumentException ex) { Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2"); Assert.IsNull (ex.InnerException, "#A3"); Assert.IsNotNull (ex.Message, "#A4"); Assert.AreEqual ("Ldtoken, Ldftn and Ldvirtftn OpCodes cannot target DynamicMethods.", ex.Message, "#A5"); Assert.IsNull (ex.ParamName, "#A6"); } try { ilgen.Emit (OpCodes.Ldtoken, method); Assert.Fail ("#B1"); } catch (ArgumentException ex) { Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2"); Assert.IsNull (ex.InnerException, "#B3"); Assert.IsNotNull (ex.Message, "#B4"); Assert.AreEqual ("Ldtoken, Ldftn and Ldvirtftn OpCodes cannot target DynamicMethods.", ex.Message, "#B5"); Assert.IsNull (ex.ParamName, "#B6"); } try { ilgen.Emit (OpCodes.Ldvirtftn, method); Assert.Fail ("#C1"); } catch (ArgumentException ex) { Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2"); Assert.IsNull (ex.InnerException, "#C3"); Assert.IsNotNull (ex.Message, "#C4"); Assert.AreEqual ("Ldtoken, Ldftn and Ldvirtftn OpCodes cannot target DynamicMethods.", ex.Message, "#C5"); Assert.IsNull (ex.ParamName, "#C6"); } }
static Composer CreateFieldComposer(FieldInfo field) { var constructor = field.FieldType.GetConstructor(new Type[] { typeof(int), typeof(MySerializeInfo) }); Debug.Assert(constructor != null, "Sync fields must have constructor taking ISyncNotify and int"); var module = Assembly.GetEntryAssembly().GetModules()[0]; DynamicMethod composerMethod = new DynamicMethod("set" + field.Name, typeof(SyncBase), new Type[] { typeof(object), typeof(int), typeof(MySerializeInfo) }, module, true); ILGenerator gen = composerMethod.GetILGenerator(); var local = gen.DeclareLocal(typeof(SyncBase)); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Castclass, field.DeclaringType); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Ldarg_2); gen.Emit(OpCodes.Newobj, constructor); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Stloc, local); gen.Emit(OpCodes.Stfld, field); gen.Emit(OpCodes.Ldloc, local); gen.Emit(OpCodes.Ret); return (Composer)composerMethod.CreateDelegate(typeof(Composer)); }
public static int Main () { DynamicMethod method = new DynamicMethod ("GetField", typeof (int), new Type [0], Type.GetType ("Host")); ILGenerator il = method.GetILGenerator (); il.Emit (OpCodes.Ldsfld, typeof (Host).GetField ( "Field", BindingFlags.Static | BindingFlags.NonPublic)); il.Emit (OpCodes.Ret); Getter g = (Getter) method.CreateDelegate (typeof (Getter)); /* * Create an object whose finalizer calls a dynamic method which * dies at the same time. * Storing into a static guarantees that this is only finalized during * shutdown. This is needed since the !shutdown case still doesn't * work. */ h = new Host (g); return 0; }
static void Main(string[] args) { if (args == null) { throw new ArgumentNullException(nameof(args)); } var action = FastMethodOperator.MainDomain .MethodBody("return 1+1;") .Return <int>() .Complie <Func <int> >(); action(); FakeMethodOperator.MainDomain .UseMethod <TestB>("TestMethod") .StaticMethodContent($@"Console.WriteLine(""Hello World!"");") .Complie <Action>(); FakeMethodOperator.MainDomain .UseMethod <TestB>("TestMethod") .MethodContent($@"Console.WriteLine(""Hello World!"");") .Complie <Action>(new TestA()); /* * 在此之前,你需要右键,选择工程文件,在你的.csproj里面 * * 写上这样一句浪漫的话: * * <PreserveCompilationContext>true</PreserveCompilationContext> */ ProxyOperator <TestAbstract> abstractBuilder = new ProxyOperator <TestAbstract>(); abstractBuilder.OopName("UTestClass"); abstractBuilder["GetName"] = "return Name;"; abstractBuilder["GetAge"] = "return Age;"; abstractBuilder.Compile(); var test = abstractBuilder.Create("UTestClass"); var delegate2 = NDelegateOperator <GetterDelegate> .Delegate("return value.ToString();"); Console.WriteLine(delegate2(1)); var delegate3 = "return value.ToString();".Delegate <GetterDelegate>(); var delegateConvt = FastMethodOperator.MainDomain .Param <string>("value") .MethodBody($@"return value==""true"" || value==""mama"";") .Return <bool>() .Complie <Func <string, bool> >(); Console.WriteLine(delegateConvt("mama")); DynamicMethod method = new DynamicMethod("GetString", null, new Type[] { typeof(TestB), typeof(string) }); ILGenerator il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Stfld, typeof(TestB).GetField("Name")); il.Emit(OpCodes.Ret); var emitAction = (Action <TestB, string>)(method.CreateDelegate(typeof(Action <TestB, string>))); var roslynAction = FastMethodOperator.MainDomain .Param <TestB>("instance") .Param <string>("value") .MethodBody("instance.Name = value;") .Return() .Complie <Action <TestB, string> >(); Stopwatch stopwatch = new Stopwatch(); stopwatch.Restart(); for (int i = 0; i < 50000; i++) { var tEntity = new TestB(); roslynAction(tEntity, "abc"); } stopwatch.Stop(); Console.WriteLine("Roslyn:\t" + stopwatch.Elapsed); stopwatch.Restart(); for (int i = 0; i < 50000; i++) { var tEntity = new TestB(); emitAction(tEntity, "abc"); } stopwatch.Stop(); Console.WriteLine("Emit:\t" + stopwatch.Elapsed); stopwatch.Restart(); for (int i = 0; i < 50000; i++) { var tEntity = new TestB(); roslynAction(tEntity, "abc"); } stopwatch.Stop(); Console.WriteLine("Roslyn:\t" + stopwatch.Elapsed); stopwatch.Restart(); for (int i = 0; i < 50000; i++) { var tEntity = new TestB(); emitAction(tEntity, "abc"); } stopwatch.Stop(); Console.WriteLine("Emit:\t" + stopwatch.Elapsed); Console.ReadKey(); }
static ForallDelegate CreateForallCallback(IntPtr gtype) { var dm = new DynamicMethod( "ContainerForallCallback", typeof(void), new Type[] { typeof(IntPtr), typeof(bool), typeof(IntPtr), typeof(IntPtr) }, typeof(GtkWorkarounds).Module, true); var invokerType = typeof(Gtk.Container.CallbackInvoker); //this was based on compiling a similar method and disassembling it ILGenerator il = dm.GetILGenerator(); var IL_002b = il.DefineLabel(); var IL_003f = il.DefineLabel(); var IL_0060 = il.DefineLabel(); var label_return = il.DefineLabel(); var loc_container = il.DeclareLocal(typeof(Gtk.Container)); var loc_obj = il.DeclareLocal(typeof(object)); var loc_invoker = il.DeclareLocal(invokerType); var loc_ex = il.DeclareLocal(typeof(Exception)); //check that the type is an exact match // prevent stack overflow, because the callback on a more derived type will handle everything il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, typeof(GLib.ObjectManager).GetMethod("gtksharp_get_type_id", BindingFlags.Static | BindingFlags.NonPublic)); il.Emit(OpCodes.Ldc_I8, gtype.ToInt64()); il.Emit(OpCodes.Newobj, typeof(IntPtr).GetConstructor(new Type[] { typeof(Int64) })); il.Emit(OpCodes.Call, typeof(IntPtr).GetMethod("op_Equality", BindingFlags.Static | BindingFlags.Public)); il.Emit(OpCodes.Brfalse, label_return); il.BeginExceptionBlock(); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Stloc, loc_container); il.Emit(OpCodes.Ldsfld, typeof(GLib.Object).GetField("Objects", BindingFlags.Static | BindingFlags.NonPublic)); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Box, typeof(IntPtr)); il.Emit(OpCodes.Callvirt, typeof(System.Collections.Hashtable).GetProperty("Item").GetGetMethod()); il.Emit(OpCodes.Stloc, loc_obj); il.Emit(OpCodes.Ldloc, loc_obj); il.Emit(OpCodes.Brfalse, IL_002b); var tref = typeof(GLib.Object).Assembly.GetType("GLib.ToggleRef"); il.Emit(OpCodes.Ldloc, loc_obj); il.Emit(OpCodes.Castclass, tref); il.Emit(OpCodes.Callvirt, tref.GetProperty("Target").GetGetMethod()); il.Emit(OpCodes.Isinst, typeof(Gtk.Container)); il.Emit(OpCodes.Stloc, loc_container); il.MarkLabel(IL_002b); il.Emit(OpCodes.Ldloc, loc_container); il.Emit(OpCodes.Brtrue, IL_003f); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_3); il.Emit(OpCodes.Call, typeof(Gtk.Container).GetMethod("gtksharp_container_base_forall", BindingFlags.Static | BindingFlags.NonPublic)); il.Emit(OpCodes.Br, IL_0060); il.MarkLabel(IL_003f); il.Emit(OpCodes.Ldloca_S, 2); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_3); il.Emit(OpCodes.Call, invokerType.GetConstructor( BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(IntPtr), typeof(IntPtr) }, null)); il.Emit(OpCodes.Ldloc, loc_container); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloc, loc_invoker); il.Emit(OpCodes.Box, invokerType); il.Emit(OpCodes.Ldftn, invokerType.GetMethod("Invoke")); il.Emit(OpCodes.Newobj, typeof(Gtk.Callback).GetConstructor( BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(object), typeof(IntPtr) }, null)); var forallMeth = typeof(Gtk.Container).GetMethod("ForAll", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(bool), typeof(Gtk.Callback) }, null); il.Emit(OpCodes.Callvirt, forallMeth); il.MarkLabel(IL_0060); il.BeginCatchBlock(typeof(Exception)); il.Emit(OpCodes.Stloc, loc_ex); il.Emit(OpCodes.Ldloc, loc_ex); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Call, typeof(GLib.ExceptionManager).GetMethod("RaiseUnhandledException")); il.Emit(OpCodes.Leave, label_return); il.EndExceptionBlock(); il.MarkLabel(label_return); il.Emit(OpCodes.Ret); return((ForallDelegate)dm.CreateDelegate(typeof(ForallDelegate))); }
public static Task <object[]> FromEvent <T>(this T obj, string eventName) { var tcs = new TaskCompletionSource <object[]>(); var tcsh = new TaskCompletionSourceHolder(tcs); Type tcshType = tcsh.GetType(); MethodInfo setResultMethodInfo = tcshType.GetMethod( "SetResult", BindingFlags.NonPublic | BindingFlags.Instance); EventInfo eventInfo = obj.GetType().GetEvent(eventName); Type eventDelegateType = eventInfo.EventHandlerType; DynamicMethod handler; if (!s_emittedHandlers.TryGetValue(eventDelegateType, out handler)) { Type returnType; List <Type> parameterTypes; GetDelegateParameterAndReturnTypes(eventDelegateType, out parameterTypes, out returnType); if (returnType != typeof(void)) { throw new NotSupportedException(); } // I'm going to create an instance-like method // so, first argument must an instance itself // i.e. TaskCompletionSourceHolder<object> *this* parameterTypes.Insert(0, tcshType); Type[] parameterTypesAr = parameterTypes.ToArray(); handler = new DynamicMethod("unnamed", returnType, parameterTypesAr, tcshType); ILGenerator ilgen = handler.GetILGenerator(); // declare local variable of type object[] LocalBuilder arr = ilgen.DeclareLocal(typeof(object[])); // push array's size onto the stack ilgen.Emit(OpCodes.Ldc_I4, parameterTypesAr.Length - 1); // create an object array of the given size ilgen.Emit(OpCodes.Newarr, typeof(object)); // and store it in the local variable ilgen.Emit(OpCodes.Stloc, arr); // iterate thru all arguments except the zero one (i.e. *this*) // and store them to the array for (int i = 1; i < parameterTypesAr.Length; i++) { // push the array onto the stack ilgen.Emit(OpCodes.Ldloc, arr); // push the argument's index onto the stack ilgen.Emit(OpCodes.Ldc_I4, i - 1); // push the argument onto the stack ilgen.Emit(OpCodes.Ldarg, i); // check if it is of a value type // and perform boxing if necessary if (parameterTypesAr[i].IsValueType) { ilgen.Emit(OpCodes.Box, parameterTypesAr[i]); } // store the value to the argument's array ilgen.Emit(OpCodes.Stelem, typeof(object)); } // load zero-argument (i.e. *this*) onto the stack ilgen.Emit(OpCodes.Ldarg_0); // load the array onto the stack ilgen.Emit(OpCodes.Ldloc, arr); // call this.SetResult(arr); ilgen.Emit(OpCodes.Call, setResultMethodInfo); // and return ilgen.Emit(OpCodes.Ret); s_emittedHandlers.Add(eventDelegateType, handler); } Delegate dEmitted = handler.CreateDelegate(eventDelegateType, tcsh); tcsh.Target = obj; tcsh.EventInfo = eventInfo; tcsh.Delegate = dEmitted; eventInfo.AddEventHandler(obj, dEmitted); return(tcs.Task); }
/// <summary> /// Creates a method for calling with the specified signature. The returned method has a signature /// of the form: /// /// (IntPtr funcAddress, arg0, arg1, ..., object[] constantPool) /// /// where IntPtr is the address of the function to be called. The arguments types are based upon /// the types that the ArgumentMarshaller requires. /// </summary> private static MethodInfo /*!*/ CreateInteropInvoker(CallingConvention convention, ArgumentMarshaller /*!*/[] /*!*/ sig, INativeType nativeRetType, bool retVoid, List <object> constantPool) { Type[] sigTypes = new Type[sig.Length + 2]; sigTypes[0] = typeof(IntPtr); for (int i = 0; i < sig.Length; i++) { sigTypes[i + 1] = sig[i].ArgumentExpression.Type; } sigTypes[sigTypes.Length - 1] = typeof(object[]); Type retType = retVoid ? typeof(void) : nativeRetType != null?nativeRetType.GetPythonType() : typeof(int); Type calliRetType = retVoid ? typeof(void) : nativeRetType != null?nativeRetType.GetNativeType() : typeof(int); #if !CTYPES_USE_SNIPPETS DynamicMethod dm = new DynamicMethod("InteropInvoker", retType, sigTypes, DynamicModule); #else TypeGen tg = Snippets.Shared.DefineType("InteropInvoker", typeof(object), false, false); MethodBuilder dm = tg.TypeBuilder.DefineMethod("InteropInvoker", CompilerHelpers.PublicStatic, retType, sigTypes); #endif ILGenerator method = dm.GetILGenerator(); LocalBuilder calliRetTmp = null, finalRetValue = null; if (dm.ReturnType != typeof(void)) { calliRetTmp = method.DeclareLocal(calliRetType); finalRetValue = method.DeclareLocal(dm.ReturnType); } // try { // emit all of the arguments, save their cleanups method.BeginExceptionBlock(); List <MarshalCleanup> cleanups = null; for (int i = 0; i < sig.Length; i++) { #if DEBUG method.Emit(OpCodes.Ldstr, String.Format("Argument #{0}, Marshaller: {1}, Native Type: {2}", i, sig[i], sig[i].NativeType)); method.Emit(OpCodes.Pop); #endif MarshalCleanup cleanup = sig[i].EmitCallStubArgument(method, i + 1, constantPool, sigTypes.Length - 1); if (cleanup != null) { if (cleanups == null) { cleanups = new List <MarshalCleanup>(); } cleanups.Add(cleanup); } } // emit the target function pointer and the calli #if DEBUG method.Emit(OpCodes.Ldstr, "!!! CALLI !!!"); method.Emit(OpCodes.Pop); #endif method.Emit(OpCodes.Ldarg_0); method.Emit(OpCodes.Calli, GetCalliSignature(convention, sig, calliRetType)); // if we have a return value we need to store it and marshal to Python // before we run any cleanup code. if (retType != typeof(void)) { #if DEBUG method.Emit(OpCodes.Ldstr, "!!! Return !!!"); method.Emit(OpCodes.Pop); #endif if (nativeRetType != null) { method.Emit(OpCodes.Stloc, calliRetTmp); nativeRetType.EmitReverseMarshalling(method, new Local(calliRetTmp), constantPool, sig.Length + 1); method.Emit(OpCodes.Stloc, finalRetValue); } else { Debug.Assert(retType == typeof(int)); // no marshalling necessary method.Emit(OpCodes.Stloc, finalRetValue); } } // } finally { // emit the cleanup code method.BeginFinallyBlock(); if (cleanups != null) { foreach (MarshalCleanup mc in cleanups) { mc.Cleanup(method); } } method.EndExceptionBlock(); // } // load the temporary value and return it. if (retType != typeof(void)) { method.Emit(OpCodes.Ldloc, finalRetValue); } method.Emit(OpCodes.Ret); #if CTYPES_USE_SNIPPETS return(tg.TypeBuilder.CreateType().GetMethod("InteropInvoker")); #else return(dm); #endif }
public static void Main() { // This dynamic method changes the private id field. It has // no name; it returns the old id value (return type int); // it takes two parameters, an instance of Example and // an int that is the new value of id; and it is declared // with Example as the owner type, so it can access all // members, public and private. // DynamicMethod changeID = new DynamicMethod( "", typeof(int), new Type[] { typeof(Example), typeof(int) }, typeof(Example) ); // Get a FieldInfo for the private field 'id'. FieldInfo fid = typeof(Example).GetField( "id", BindingFlags.NonPublic | BindingFlags.Instance ); ILGenerator ilg = changeID.GetILGenerator(); // Push the current value of the id field onto the // evaluation stack. It's an instance field, so load the // instance of Example before accessing the field. ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldfld, fid); // Load the instance of Example again, load the new value // of id, and store the new field value. ilg.Emit(OpCodes.Ldarg_0); ilg.Emit(OpCodes.Ldarg_1); ilg.Emit(OpCodes.Stfld, fid); // The original value of the id field is now the only // thing on the stack, so return from the call. ilg.Emit(OpCodes.Ret); // Create a delegate that uses changeID in the ordinary // way, as a static method that takes an instance of // Example and an int. // UseLikeStatic uls = (UseLikeStatic)changeID.CreateDelegate( typeof(UseLikeStatic) ); // Create an instance of Example with an id of 42. // Example ex = new Example(42); // Create a delegate that is bound to the instance of // of Example. This is possible because the first // parameter of changeID is of type Example. The // delegate has all the parameters of changeID except // the first. UseLikeInstance uli = (UseLikeInstance)changeID.CreateDelegate( typeof(UseLikeInstance), ex ); // First, change the value of id by calling changeID as // a static method, passing in the instance of Example. // Console.WriteLine( "Change the value of id; previous value: {0}", uls(ex, 1492) ); // Change the value of id again using the delegate bound // to the instance of Example. // Console.WriteLine( "Change the value of id; previous value: {0}", uli(2700) ); Console.WriteLine("Final value of id: {0}", ex.ID); // Now repeat the process with a class that derives // from Example. // DerivedFromExample dfex = new DerivedFromExample(71); uli = (UseLikeInstance)changeID.CreateDelegate( typeof(UseLikeInstance), dfex ); Console.WriteLine( "Change the value of id; previous value: {0}", uls(dfex, 73) ); Console.WriteLine( "Change the value of id; previous value: {0}", uli(79) ); Console.WriteLine("Final value of id: {0}", dfex.ID); }
private static Action <T, ExecutionContext> GenerateMethod <T>(string svcName, int registerCleanCount) { Type[] argTypes = new Type[] { typeof(T), typeof(ExecutionContext) }; DynamicMethod method = new DynamicMethod(svcName, null, argTypes); MethodInfo methodInfo = typeof(T).GetMethod(svcName); ParameterInfo[] methodArgs = methodInfo.GetParameters(); ILGenerator generator = method.GetILGenerator(); void ConvertToArgType(Type sourceType) { CheckIfTypeIsSupported(sourceType, svcName); switch (Type.GetTypeCode(sourceType)) { case TypeCode.UInt32: generator.Emit(OpCodes.Conv_U4); break; case TypeCode.Int32: generator.Emit(OpCodes.Conv_I4); break; case TypeCode.UInt16: generator.Emit(OpCodes.Conv_U2); break; case TypeCode.Int16: generator.Emit(OpCodes.Conv_I2); break; case TypeCode.Byte: generator.Emit(OpCodes.Conv_U1); break; case TypeCode.SByte: generator.Emit(OpCodes.Conv_I1); break; case TypeCode.Boolean: generator.Emit(OpCodes.Conv_I4); generator.Emit(OpCodes.Ldc_I4_1); generator.Emit(OpCodes.And); break; } } void ConvertToFieldType(Type sourceType) { CheckIfTypeIsSupported(sourceType, svcName); switch (Type.GetTypeCode(sourceType)) { case TypeCode.UInt32: case TypeCode.Int32: case TypeCode.UInt16: case TypeCode.Int16: case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Boolean: generator.Emit(OpCodes.Conv_U8); break; } } RAttribute GetRegisterAttribute(ParameterInfo parameterInfo) { RAttribute argumentAttribute = (RAttribute)parameterInfo.GetCustomAttribute(typeof(RAttribute)); if (argumentAttribute == null) { throw new InvalidOperationException($"Method \"{svcName}\" is missing a {typeof(RAttribute).Name} attribute on parameter \"{parameterInfo.Name}\""); } return(argumentAttribute); } // For functions returning output values, the first registers // are used to hold pointers where the value will be stored, // so they can't be used to pass argument and we must // skip them. int byRefArgsCount = 0; for (int index = 0; index < methodArgs.Length; index++) { if (methodArgs[index].ParameterType.IsByRef) { byRefArgsCount++; } } BindingFlags staticNonPublic = BindingFlags.NonPublic | BindingFlags.Static; // Print all the arguments for debugging purposes. int inputArgsCount = methodArgs.Length - byRefArgsCount; if (inputArgsCount != 0) { generator.Emit(OpCodes.Ldc_I4, inputArgsCount); generator.Emit(OpCodes.Newarr, typeof(object)); string argsFormat = svcName; for (int index = 0; index < methodArgs.Length; index++) { Type argType = methodArgs[index].ParameterType; // Ignore out argument for printing if (argType.IsByRef) { continue; } RAttribute registerAttribute = GetRegisterAttribute(methodArgs[index]); argsFormat += $" {methodArgs[index].Name}: 0x{{{index}:X8}},"; generator.Emit(OpCodes.Dup); generator.Emit(OpCodes.Ldc_I4, index); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldc_I4, registerAttribute.Index); MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.GetX)); generator.Emit(OpCodes.Call, info); generator.Emit(OpCodes.Box, typeof(ulong)); generator.Emit(OpCodes.Stelem_Ref); } argsFormat = argsFormat.Substring(0, argsFormat.Length - 1); generator.Emit(OpCodes.Ldstr, argsFormat); } else { generator.Emit(OpCodes.Ldnull); generator.Emit(OpCodes.Ldstr, svcName); } MethodInfo printArgsMethod = typeof(SyscallTable).GetMethod(nameof(PrintArguments), staticNonPublic); generator.Emit(OpCodes.Call, printArgsMethod); // Call the SVC function handler. generator.Emit(OpCodes.Ldarg_0); List <(LocalBuilder, RAttribute)> locals = new List <(LocalBuilder, RAttribute)>(); for (int index = 0; index < methodArgs.Length; index++) { Type argType = methodArgs[index].ParameterType; RAttribute registerAttribute = GetRegisterAttribute(methodArgs[index]); if (argType.IsByRef) { argType = argType.GetElementType(); LocalBuilder local = generator.DeclareLocal(argType); locals.Add((local, registerAttribute)); if (!methodArgs[index].IsOut) { generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldc_I4, registerAttribute.Index); MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.GetX)); generator.Emit(OpCodes.Call, info); ConvertToArgType(argType); generator.Emit(OpCodes.Stloc, local); } generator.Emit(OpCodes.Ldloca, local); } else { generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldc_I4, registerAttribute.Index); MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.GetX)); generator.Emit(OpCodes.Call, info); ConvertToArgType(argType); } } generator.Emit(OpCodes.Call, methodInfo); Type retType = methodInfo.ReturnType; // Print result code. if (retType == typeof(KernelResult)) { MethodInfo printResultMethod = typeof(SyscallTable).GetMethod(nameof(PrintResult), staticNonPublic); generator.Emit(OpCodes.Dup); generator.Emit(OpCodes.Ldstr, svcName); generator.Emit(OpCodes.Call, printResultMethod); } uint registerInUse = 0; // Save return value into register X0 (when the method has a return value). if (retType != typeof(void)) { CheckIfTypeIsSupported(retType, svcName); LocalBuilder tempLocal = generator.DeclareLocal(retType); generator.Emit(OpCodes.Stloc, tempLocal); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldc_I4, 0); generator.Emit(OpCodes.Ldloc, tempLocal); ConvertToFieldType(retType); MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.SetX)); generator.Emit(OpCodes.Call, info); registerInUse |= 1u << 0; } for (int index = 0; index < locals.Count; index++) { (LocalBuilder local, RAttribute attribute) = locals[index]; if ((registerInUse & (1u << attribute.Index)) != 0) { throw new InvalidSvcException($"Method \"{svcName}\" has conflicting output values at register index \"{attribute.Index}\"."); } generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldc_I4, attribute.Index); generator.Emit(OpCodes.Ldloc, local); ConvertToFieldType(local.LocalType); MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.SetX)); generator.Emit(OpCodes.Call, info); registerInUse |= 1u << attribute.Index; } // Zero out the remaining unused registers. for (int i = 0; i < registerCleanCount; i++) { if ((registerInUse & (1u << i)) != 0) { continue; } generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Ldc_I8, 0L); MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.SetX)); generator.Emit(OpCodes.Call, info); } generator.Emit(OpCodes.Ret); return((Action <T, ExecutionContext>)method.CreateDelegate(typeof(Action <T, ExecutionContext>))); }
private static ObjectActivator GenerateDelegate(Type type, params Type[] types) { var ctors = type.GetConstructors(); ConstructorInfo ctor = null; ParameterInfo[] paramsInfo = null; foreach (var c in ctors) { var p = c.GetParameters(); if (p.Length != types.Length) continue; if (p.Length == 0) { ctor = c; paramsInfo = p; break; } var count = p.Select(a => a.ParameterType).Zip(types, (t1, t2) => t1 == t2 || t1.IsAssignableFrom(t2) || t2.IsAssignableFrom(t1) ? 1 : 0).Sum(); if (count != types.Length) continue; ctor = c; paramsInfo = p; break; } var method = new DynamicMethod("CreateInstance", type, new[] { typeof(object[]) }, true); // skip visibility is on to allow instantiation of anonyopus type wrappers var il = method.GetILGenerator(); for (var i = 0; i < paramsInfo.Length; i++) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldelem_Ref); il.EmitCastToReference(paramsInfo[i].ParameterType); } il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Ret); var activator = (ObjectActivator)method.CreateDelegate(typeof(ObjectActivator)); ////create a single param of type object[] //ParameterExpression param = Expression.Parameter(typeof(object[]), "args"); //Expression[] argsExp = new Expression[paramsInfo.Length]; ////pick each arg from the params array ////and create a typed expression of them //for (int i = 0; i < paramsInfo.Length; i++) //{ // Expression index = Expression.Constant(i); // Type paramType = paramsInfo[i].ParameterType; // Expression paramAccessorExp = Expression.ArrayIndex(param, index); // Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType); // argsExp[i] = paramCastExp; //} ////make a NewExpression that calls the ////ctor with the args we just created //NewExpression newExp = Expression.New(ctor, argsExp); ////create a lambda with the New ////Expression as body and our param object[] as arg //LambdaExpression lambda = Expression.Lambda(typeof(ObjectActivator), newExp, param); //var activator = (ObjectActivator)lambda.Compile(); return activator; }
public static Func <IDataReader, T> GetClassDeserializer <T>(IDataReader reader) { DynamicMethod dm = new DynamicMethod("Deserialize" + Guid.NewGuid().ToString(), typeof(T), new Type[] { typeof(IDataReader) }, true); var il = dm.GetILGenerator(); var properties = typeof(T) .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(p => new { Name = p.Name, Setter = p.GetSetMethod(), Type = p.PropertyType }) .Where(info => info.Setter != null) .ToList(); var names = new List <string>(); for (int i = 0; i < reader.FieldCount; i++) { names.Add(reader.GetName(i)); } var setters = ( from n in names select new { Name = n, Info = properties.FirstOrDefault(p => p.Name == n) } ).ToList(); var getItem = typeof(IDataRecord).GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(p => p.GetIndexParameters().Any() && p.GetIndexParameters()[0].ParameterType == typeof(int)) .Select(p => p.GetGetMethod()).First(); int index = 0; // stack is empty il.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes)); // stack is now [target] foreach (var item in setters) { if (item.Info != null) { il.Emit(OpCodes.Dup); // stack is now [target][target] Label isDbNullLabel = il.DefineLabel(); Label finishLabel = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); // stack is now [target][target][reader] EmitInt32(il, index++); // stack is now [target][target][reader][index] il.Emit(OpCodes.Callvirt, getItem); // stack is now [target][target][value-as-object] il.Emit(OpCodes.Dup); // stack is now [target][target][value][value] il.Emit(OpCodes.Isinst, typeof(DBNull)); // stack is now [target][target][value-as-object][DBNull or null] il.Emit(OpCodes.Brtrue_S, isDbNullLabel); // stack is now [target][target][value-as-object] il.Emit(OpCodes.Unbox_Any, item.Info.Type); // stack is now [target][target][typed-value] il.Emit(OpCodes.Callvirt, item.Info.Setter); // stack is now [target] il.Emit(OpCodes.Br_S, finishLabel); // stack is now [target] il.MarkLabel(isDbNullLabel); // incoming stack: [target][target][value] il.Emit(OpCodes.Pop); // stack is now [target][target] il.Emit(OpCodes.Pop); // stack is now [target] il.MarkLabel(finishLabel); } } il.Emit(OpCodes.Ret); // stack is empty return((Func <IDataReader, T>)dm.CreateDelegate(typeof(Func <IDataReader, T>))); }
public static MethodDelegate CreateMethod(MethodInfo method) { ParameterInfo[] pi = method.GetParameters(); DynamicMethod dm = new DynamicMethod("DynamicMethod", typeof(object), new Type[] { typeof(object), typeof(object[]) }, typeof(DynamicMethodFactory), true); ILGenerator il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); for (int index = 0; index < pi.Length; index++) { il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldc_I4, index); Type parameterType = pi[index].ParameterType; if (parameterType.IsByRef) { parameterType = parameterType.GetElementType(); if (parameterType.IsValueTypeEx()) { il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Unbox, parameterType); } else { il.Emit(OpCodes.Ldelema, parameterType); } } else { il.Emit(OpCodes.Ldelem_Ref); if (parameterType.IsValueTypeEx()) { il.Emit(OpCodes.Unbox, parameterType); il.Emit(OpCodes.Ldobj, parameterType); } } } if ((method.IsAbstract || method.IsVirtual) && !method.IsFinal && !method.DeclaringType.IsSealedEx()) { il.Emit(OpCodes.Callvirt, method); } else { il.Emit(OpCodes.Call, method); } if (method.ReturnType == typeof(void)) { il.Emit(OpCodes.Ldnull); } else if (method.ReturnType.IsValueTypeEx()) { il.Emit(OpCodes.Box, method.ReturnType); } il.Emit(OpCodes.Ret); return((MethodDelegate)dm.CreateDelegate(typeof(MethodDelegate))); }
/// <summary>Calls the given function when the animation is over.</summary> public void OnDone(DynamicMethod <Nitro.Void> method) { Done = method; }
/// <summary> /// Dynamically creates a Comparison delegate that compare instances based on a single named property using System.Reflection.Emit. /// </summary> /// <param name="type">The type.</param> /// <param name="propName">Name of property to base comparison on</param> /// <param name="ascending">true to search in ascending order, false to sort in descending order</param> /// <returns> /// A Comparison delegate for the given property. /// </returns> /// <remarks>This cannot be used for value types and does not support fields.</remarks> /// <exception cref="System.InvalidOperationException">If T is a value type.</exception> /// <exception cref="System.ArgumentException">If propName is not a name of a public readable property in class T</exception> /// <exception cref="System.ArgumentNullException">If propName is null.</exception> public static Comparison CreatePropertyComparisonThroughEmit(Type type, String propName, bool ascending) { if (propName == null) { throw new ArgumentNullException("propName"); } if (type.IsValueType) { throw new InvalidOperationException("Cannot create property comparer using CreatePropertyComparerThroughEmit for value types."); } PropertyInfo property = type.GetProperty(propName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (property == null) { throw new ArgumentException("Public property named '" + propName + "' not found in type " + type.Name); } Type propertyType = property.PropertyType; MethodInfo propGetMethod = property.GetGetMethod(); if (propGetMethod == null) { throw new ArgumentException("Public get method not found for property '" + propName + "' not found in type " + type.Name); } DynamicMethod dynMethod = new DynamicMethod("Compare" + propName, typeof(int), new Type[] { type, type }, type); ILGenerator ilgen = dynMethod.GetILGenerator(); if (propertyType == typeof(String)) { // Call String.Compare(o1.<prop>,s2.<prop>,StringComparison.CurrentCultureIgnoreCase) ilgen.Emit(OpCodes.Ldarg_0); ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null); ilgen.Emit(OpCodes.Ldarg_1); ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null); ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.EmitCall(OpCodes.Call, stringCompareMethod, null); } else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable <>)) { // Call Nullable<T>.Compare ilgen.Emit(OpCodes.Ldarg_0); ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null); ilgen.Emit(OpCodes.Ldarg_1); ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null); MethodInfo compareMethod = nullableGenericCompareMethod.MakeGenericMethod(Nullable.GetUnderlyingType(propertyType)); ilgen.EmitCall(OpCodes.Call, compareMethod, null); } else { // Try typed CompareTo (defined in IComparable<T> generic interface type) first. Type genericIComparableType = typeof(IComparable <>).MakeGenericType(propertyType); MethodInfo genericIComparableCompareToMethod = genericIComparableType.GetMethod("CompareTo"); MethodInfo compareToMethod = GetMethodImplementation(propertyType, genericIComparableCompareToMethod); bool nonGenericCompare = false; if (compareToMethod == null) { // Then, try non-generic CompareTo (defined in IComparable interface type) compareToMethod = GetMethodImplementation(propertyType, nonGenericCompareToMethod); if (compareToMethod == null) { throw new ArgumentException("Type of property '" + propName + "' does not support comparison"); } nonGenericCompare = true; } if (propertyType.IsValueType == false) { // Call o1.CompareTo(o2); Label p1NotNullLabel = ilgen.DefineLabel(); Label p2NotNullLabel = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null); ilgen.Emit(OpCodes.Stloc_0); ilgen.Emit(OpCodes.Ldarg_1); ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null); ilgen.Emit(OpCodes.Stloc_1); ilgen.Emit(OpCodes.Ldloc_0); ilgen.Emit(OpCodes.Brtrue_S, p1NotNullLabel); ilgen.Emit(OpCodes.Ldloc_1); ilgen.Emit(OpCodes.Brtrue_S, p2NotNullLabel); ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(p2NotNullLabel); if (ascending) { ilgen.Emit(OpCodes.Ldc_I4_M1); } else { ilgen.Emit(OpCodes.Ldc_I4_1); } ilgen.Emit(OpCodes.Ret); ilgen.MarkLabel(p1NotNullLabel); ilgen.Emit(OpCodes.Ldloc_0); ilgen.Emit(OpCodes.Ldloc_1); ilgen.EmitCall(OpCodes.Call, compareToMethod, null); } else { // Call o1.<prop>.CompareTo(o2.<prop>); ilgen.DeclareLocal(propertyType); ilgen.Emit(OpCodes.Ldarg_0); ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null); ilgen.Emit(OpCodes.Stloc_0); ilgen.Emit(OpCodes.Ldloca_S, (byte)0); ilgen.Emit(OpCodes.Ldarg_1); ilgen.EmitCall(OpCodes.Callvirt, propGetMethod, null); if (nonGenericCompare) { ilgen.Emit(OpCodes.Box); } ilgen.EmitCall(OpCodes.Call, compareToMethod, null); } } if (ascending == false) { ilgen.Emit(OpCodes.Neg); } ilgen.Emit(OpCodes.Ret); return((Comparison)dynMethod.CreateDelegate(typeof(Comparison))); }
// Create factory function that can convert a IDataReader record into a POCO public Delegate GetFactory(string sql, string connString, int firstColumn, int countColumns, IDataReader r) { // Check cache var key = Tuple.Create <string, string, int, int>(sql, connString, firstColumn, countColumns); return(PocoFactories.Get(key, () => { // Create the method var m = new DynamicMethod("petapoco_factory_" + PocoFactories.Count.ToString(), type, new Type[] { typeof(IDataReader) }, true); var il = m.GetILGenerator(); var mapper = Mappers.GetMapper(type); #if !PETAPOCO_NO_DYNAMIC if (type == typeof(object)) { // var poco=new T() il.Emit(OpCodes.Newobj, typeof(System.Dynamic.ExpandoObject).GetConstructor(Type.EmptyTypes)); // obj MethodInfo fnAdd = typeof(IDictionary <string, object>).GetMethod("Add"); // Enumerate all fields generating a set assignment for the column for (int i = firstColumn; i < firstColumn + countColumns; i++) { var srcType = r.GetFieldType(i); il.Emit(OpCodes.Dup); // obj, obj il.Emit(OpCodes.Ldstr, r.GetName(i)); // obj, obj, fieldname // Get the converter Func <object, object> converter = mapper.GetFromDbConverter((PropertyInfo)null, srcType); /* * if (ForceDateTimesToUtc && converter == null && srcType == typeof(DateTime)) * converter = delegate(object src) { return new DateTime(((DateTime)src).Ticks, DateTimeKind.Utc); }; */ // Setup stack for call to converter AddConverterToStack(il, converter); // r[i] il.Emit(OpCodes.Ldarg_0); // obj, obj, fieldname, converter?, rdr il.Emit(OpCodes.Ldc_I4, i); // obj, obj, fieldname, converter?, rdr,i il.Emit(OpCodes.Callvirt, fnGetValue); // obj, obj, fieldname, converter?, value // Convert DBNull to null il.Emit(OpCodes.Dup); // obj, obj, fieldname, converter?, value, value il.Emit(OpCodes.Isinst, typeof(DBNull)); // obj, obj, fieldname, converter?, value, (value or null) var lblNotNull = il.DefineLabel(); il.Emit(OpCodes.Brfalse_S, lblNotNull); // obj, obj, fieldname, converter?, value il.Emit(OpCodes.Pop); // obj, obj, fieldname, converter? if (converter != null) { il.Emit(OpCodes.Pop); // obj, obj, fieldname, } il.Emit(OpCodes.Ldnull); // obj, obj, fieldname, null if (converter != null) { var lblReady = il.DefineLabel(); il.Emit(OpCodes.Br_S, lblReady); il.MarkLabel(lblNotNull); il.Emit(OpCodes.Callvirt, fnInvoke); il.MarkLabel(lblReady); } else { il.MarkLabel(lblNotNull); } il.Emit(OpCodes.Callvirt, fnAdd); } } else #endif if (type.IsValueType || type == typeof(string) || type == typeof(byte[])) { // Do we need to install a converter? var srcType = r.GetFieldType(0); var converter = GetConverter(mapper, null, srcType, type); // "if (!rdr.IsDBNull(i))" il.Emit(OpCodes.Ldarg_0); // rdr il.Emit(OpCodes.Ldc_I4_0); // rdr,0 il.Emit(OpCodes.Callvirt, fnIsDBNull); // bool var lblCont = il.DefineLabel(); il.Emit(OpCodes.Brfalse_S, lblCont); il.Emit(OpCodes.Ldnull); // null var lblFin = il.DefineLabel(); il.Emit(OpCodes.Br_S, lblFin); il.MarkLabel(lblCont); // Setup stack for call to converter AddConverterToStack(il, converter); il.Emit(OpCodes.Ldarg_0); // rdr il.Emit(OpCodes.Ldc_I4_0); // rdr,0 il.Emit(OpCodes.Callvirt, fnGetValue); // value // Call the converter if (converter != null) { il.Emit(OpCodes.Callvirt, fnInvoke); } il.MarkLabel(lblFin); il.Emit(OpCodes.Unbox_Any, type); // value converted } else { // var poco=new T() il.Emit(OpCodes.Newobj, type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null)); // Enumerate all fields generating a set assignment for the column for (int i = firstColumn; i < firstColumn + countColumns; i++) { // Get the PocoColumn for this db column, ignore if not known PocoColumn pc; if (!Columns.TryGetValue(r.GetName(i), out pc)) { continue; } // Get the source type for this column var srcType = r.GetFieldType(i); var dstType = pc.PropertyInfo.PropertyType; // "if (!rdr.IsDBNull(i))" il.Emit(OpCodes.Ldarg_0); // poco,rdr il.Emit(OpCodes.Ldc_I4, i); // poco,rdr,i il.Emit(OpCodes.Callvirt, fnIsDBNull); // poco,bool var lblNext = il.DefineLabel(); il.Emit(OpCodes.Brtrue_S, lblNext); // poco il.Emit(OpCodes.Dup); // poco,poco // Do we need to install a converter? var converter = GetConverter(mapper, pc, srcType, dstType); // Fast bool Handled = false; if (converter == null) { var valuegetter = typeof(IDataRecord).GetMethod("Get" + srcType.Name, new Type[] { typeof(int) }); if (valuegetter != null && valuegetter.ReturnType == srcType && (valuegetter.ReturnType == dstType || valuegetter.ReturnType == Nullable.GetUnderlyingType(dstType))) { il.Emit(OpCodes.Ldarg_0); // *,rdr il.Emit(OpCodes.Ldc_I4, i); // *,rdr,i il.Emit(OpCodes.Callvirt, valuegetter); // *,value // Convert to Nullable if (Nullable.GetUnderlyingType(dstType) != null) { il.Emit(OpCodes.Newobj, dstType.GetConstructor(new Type[] { Nullable.GetUnderlyingType(dstType) })); } il.Emit(OpCodes.Callvirt, pc.PropertyInfo.GetSetMethod(true)); // poco Handled = true; } } // Not so fast if (!Handled) { // Setup stack for call to converter AddConverterToStack(il, converter); // "value = rdr.GetValue(i)" il.Emit(OpCodes.Ldarg_0); // *,rdr il.Emit(OpCodes.Ldc_I4, i); // *,rdr,i il.Emit(OpCodes.Callvirt, fnGetValue); // *,value // Call the converter if (converter != null) { il.Emit(OpCodes.Callvirt, fnInvoke); } // Assign it il.Emit(OpCodes.Unbox_Any, pc.PropertyInfo.PropertyType); // poco,poco,value il.Emit(OpCodes.Callvirt, pc.PropertyInfo.GetSetMethod(true)); // poco } il.MarkLabel(lblNext); } var fnOnLoaded = RecurseInheritedTypes <MethodInfo>(type, (x) => x.GetMethod("OnLoaded", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null)); if (fnOnLoaded != null) { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Callvirt, fnOnLoaded); } } il.Emit(OpCodes.Ret); // Cache it, return it return m.CreateDelegate(Expression.GetFuncType(typeof(IDataReader), type)); } )); }
/// <summary> /// Allows you to automatically populate a target property/field from output parameters. It actually /// creates an InputOutput parameter, so you can still pass data in. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="target">The object whose property/field you wish to populate.</param> /// <param name="expression">A MemberExpression targeting a property/field of the target (or descendant thereof.)</param> /// <param name="dbType"></param> /// <param name="size">The size to set on the parameter. Defaults to 0, or DbString.DefaultLength in case of strings.</param> /// <returns>The DynamicParameters instance</returns> public DynamicParameters Output <T>(T target, Expression <Func <T, object> > expression, DbType?dbType = null, int?size = null) { var failMessage = "Expression must be a property/field chain off of a(n) {0} instance"; failMessage = string.Format(failMessage, typeof(T).Name); Action @throw = () => { throw new InvalidOperationException(failMessage); }; // Is it even a MemberExpression? var lastMemberAccess = expression.Body as MemberExpression; if (lastMemberAccess == null || (!(lastMemberAccess.Member is PropertyInfo) && !(lastMemberAccess.Member is FieldInfo))) { if (expression.Body.NodeType == ExpressionType.Convert && expression.Body.Type == typeof(object) && ((UnaryExpression)expression.Body).Operand is MemberExpression) { // It's got to be unboxed lastMemberAccess = (MemberExpression)((UnaryExpression)expression.Body).Operand; } else { @throw(); } } // Does the chain consist of MemberExpressions leading to a ParameterExpression of type T? MemberExpression diving = lastMemberAccess; // Retain a list of member names and the member expressions so we can rebuild the chain. List <string> names = new List <string>(); List <MemberExpression> chain = new List <MemberExpression>(); do { // Insert the names in the right order so expression // "Post.Author.Name" becomes parameter "PostAuthorName" names.Insert(0, diving?.Member.Name); chain.Insert(0, diving); var constant = diving?.Expression as ParameterExpression; diving = diving?.Expression as MemberExpression; if (constant != null && constant.Type == typeof(T)) { break; } else if (diving == null || (!(diving.Member is PropertyInfo) && !(diving.Member is FieldInfo))) { @throw(); } }while (diving != null); var dynamicParamName = string.Join(string.Empty, names.ToArray()); // Before we get all emitty... var lookup = string.Join("|", names.ToArray()); var cache = CachedOutputSetters <T> .Cache; var setter = (Action <object, DynamicParameters>)cache[lookup]; if (setter != null) { goto MAKECALLBACK; } // Come on let's build a method, let's build it, let's build it now! var dm = new DynamicMethod($"ExpressionParam{Guid.NewGuid()}", null, new[] { typeof(object), GetType() }, true); var il = dm.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); // [object] il.Emit(OpCodes.Castclass, typeof(T)); // [T] // Count - 1 to skip the last member access var i = 0; for (; i < (chain.Count - 1); i++) { var member = chain[0].Member; if (member is PropertyInfo) { var get = ((PropertyInfo)member).GetGetMethod(true); il.Emit(OpCodes.Callvirt, get); // [Member{i}] } else // Else it must be a field! { il.Emit(OpCodes.Ldfld, ((FieldInfo)member)); // [Member{i}] } } var paramGetter = GetType().GetMethod("Get", new Type[] { typeof(string) }).MakeGenericMethod(lastMemberAccess.Type); il.Emit(OpCodes.Ldarg_1); // [target] [DynamicParameters] il.Emit(OpCodes.Ldstr, dynamicParamName); // [target] [DynamicParameters] [ParamName] il.Emit(OpCodes.Callvirt, paramGetter); // [target] [value], it's already typed thanks to generic method // GET READY var lastMember = lastMemberAccess.Member; if (lastMember is PropertyInfo) { var set = ((PropertyInfo)lastMember).GetSetMethod(true); il.Emit(OpCodes.Callvirt, set); // SET } else { il.Emit(OpCodes.Stfld, ((FieldInfo)lastMember)); // SET } il.Emit(OpCodes.Ret); // GO setter = (Action <object, DynamicParameters>)dm.CreateDelegate(typeof(Action <object, DynamicParameters>)); lock (cache) { cache[lookup] = setter; } // Queue the preparation to be fired off when adding parameters to the DbCommand MAKECALLBACK: (outputCallbacks ?? (outputCallbacks = new List <Action>())).Add(() => { // Finally, prep the parameter and attach the callback to it ParamInfo parameter; var targetMemberType = lastMemberAccess?.Type; int sizeToSet = (!size.HasValue && targetMemberType == typeof(string)) ? DbString.DefaultLength : size ?? 0; if (parameters.TryGetValue(dynamicParamName, out parameter)) { parameter.ParameterDirection = parameter.AttachedParam.Direction = ParameterDirection.InputOutput; if (parameter.AttachedParam.Size == 0) { parameter.Size = parameter.AttachedParam.Size = sizeToSet; } } else { SqlMapper.ITypeHandler handler; dbType = (!dbType.HasValue) #pragma warning disable 618 ? SqlMapper.LookupDbType(targetMemberType, targetMemberType?.Name, true, out handler) #pragma warning restore 618 : dbType; // CameFromTemplate property would not apply here because this new param // Still needs to be added to the command Add(dynamicParamName, expression.Compile().Invoke(target), null, ParameterDirection.InputOutput, sizeToSet); } parameter = parameters[dynamicParamName]; parameter.OutputCallback = setter; parameter.OutputTarget = target; }); return(this); }
public static void InstallDispatchHandler(MethodBase method) { var method_token = MethodToken(method); if (_DispatchHandlers.Contains(method_token)) { _Logger.Debug($"Not installing dispatch handler for {method.Name} ({method_token}) - it's already installed"); return; } var parms = method.GetParameters(); int ptypes_offs = 1; if (method.IsStatic) { ptypes_offs = 0; } var ptypes = new Type[parms.Length + ptypes_offs]; if (!method.IsStatic) { ptypes[0] = method.DeclaringType; } for (int i = 0; i < parms.Length; i++) { ptypes[i + ptypes_offs] = parms[i].ParameterType; } var method_returns = false; if (method is MethodInfo) { if (((MethodInfo)method).ReturnType != typeof(void)) { method_returns = true; } } var dm = new DynamicMethod( $"DISPATCH HANDLER FOR METHOD TOKEN {method_token}", method is MethodInfo ? ((MethodInfo)method).ReturnType : typeof(void), ptypes, method.Module, skipVisibility: true ); var il = dm.GetILGenerator(); var loc_args = il.DeclareLocal(typeof(object[])); loc_args.SetLocalSymInfo("args"); var loc_target = il.DeclareLocal(typeof(object)); loc_target.SetLocalSymInfo("target"); if (method.IsStatic) { il.Emit(OpCodes.Ldnull); } else { il.Emit(OpCodes.Ldarg_0); } il.Emit(OpCodes.Stloc, loc_target); int ary_size = ptypes.Length - 1; if (method.IsStatic) { ary_size = ptypes.Length; } il.Emit(OpCodes.Ldc_I4, ary_size); il.Emit(OpCodes.Newarr, typeof(object)); il.Emit(OpCodes.Stloc, loc_args); for (int i = 0; i < ary_size; i++) { il.Emit(OpCodes.Ldloc, loc_args); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldarg, i + ptypes_offs); if (ptypes[i + ptypes_offs].IsValueType) { il.Emit(OpCodes.Box, ptypes[i + ptypes_offs]); } il.Emit(OpCodes.Stelem, typeof(object)); } il.Emit(OpCodes.Ldc_I8, method_token); il.Emit(OpCodes.Ldloc, loc_target); il.Emit(OpCodes.Ldloc, loc_args); il.Emit(OpCodes.Call, _HandleDispatchMethod); if (!method_returns) { il.Emit(OpCodes.Pop); } if (method_returns && method is MethodInfo && ((MethodInfo)method).ReturnType.IsValueType) { il.Emit(OpCodes.Unbox_Any, ((MethodInfo)method).ReturnType); } il.Emit(OpCodes.Ret); RuntimeDetour.Detour( from: method, to: dm ); _Trampolines[method_token] = RuntimeDetour.CreateOrigTrampoline(method); _DispatchHandlers.Add(method_token); _Logger.Debug($"Installed dispatch handler for {method.Name} (token {method_token})"); }
public DynamicMethodReference(ModuleDefinition module, DynamicMethod dm) : base("", module.TypeSystem.Void) { DynamicMethod = dm; }
/// <summary> /// Creates a new MPI delegate from a reduction operation. /// </summary> private MPIDelegate MakeMPIDelegate(ReductionOperation <T> op) { if (mpiDelegateMethod == null) { unsafe { // Build the new mpiDelegateMethod mpiDelegateMethod = new DynamicMethod("reduce:" + typeof(T).ToString(), typeof(void), // op invec inoutvec count datatype new Type[] { typeof(ReductionOperation <T>), typeof(void *), typeof(void *), typeof(int *), typeof(MPI_Datatype *) }, typeof(ReductionOperation <T>)); } ILGenerator generator = mpiDelegateMethod.GetILGenerator(); // Local variables: /*loopCounter*/ generator.DeclareLocal(typeof(int)); /*count*/ generator.DeclareLocal(typeof(int)); // Labels we'll be using to jump around Label loopStart = generator.DefineLabel(); Label loopDone = generator.DefineLabel(); // Initialize loopCounter with zero generator.Emit(OpCodes.Ldc_I4_0); generator.Emit(OpCodes.Stloc_0); // Load the count into "count" generator.Emit(OpCodes.Ldarg_3); generator.Emit(OpCodes.Ldind_I4); // TODO: Can we assume "int" is always 32 bits? It is for Windows 32- and 64-bit generator.Emit(OpCodes.Stloc_1); // We're at the beginning of the loop generator.MarkLabel(loopStart); // Test to see whether we're done. If so, jump to loopDone generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ldloc_1); generator.Emit(OpCodes.Clt); generator.Emit(OpCodes.Brfalse, loopDone); // Load the address of inoutvec[loopCounter] onto the stack, to be used after we invoke the delegate generator.Emit(OpCodes.Ldarg_2); // Load the delegate onto the stack generator.Emit(OpCodes.Ldarg_0); // Load the first argument (invec[loopCounter]) to the user delegate generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldobj, typeof(T)); // Load the second argument (inoutvec[loopCounter]) to the user delegate generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Ldobj, typeof(T)); // Call the delegate generator.EmitCall(OpCodes.Callvirt, typeof(ReductionOperation <T>).GetMethod("Invoke", new Type[] { typeof(T), typeof(T) }), null); // Store the intermediate back into inoutvec generator.Emit(OpCodes.Stobj, typeof(T)); // Increment the loop count generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ldc_I4_1); generator.Emit(OpCodes.Add); generator.Emit(OpCodes.Stloc_0); // Increment invec by the size of T generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Sizeof, typeof(T)); generator.Emit(OpCodes.Add); generator.Emit(OpCodes.Starg, 1); // Increment inoutvec by the size of T generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Sizeof, typeof(T)); generator.Emit(OpCodes.Add); generator.Emit(OpCodes.Starg, 2); // Jump to the beginning of the loop generator.Emit(OpCodes.Br, loopStart); // End of our function generator.MarkLabel(loopDone); generator.Emit(OpCodes.Ret); } // Return a delegate to call the mpiDelegateMethod return((MPIDelegate)mpiDelegateMethod.CreateDelegate(typeof(MPIDelegate), op)); }
public DynamicResolver(DynamicMethod dynamicMethod, ILGenerator ilGenerator) { this.dynamicMethod = dynamicMethod; inst = factoryByDynamicILGenerator(ilGenerator); }
internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyInfo, bool ShowReadOnlyProperties) { var setMethod = propertyInfo.GetSetMethod(ShowReadOnlyProperties); if (setMethod == null) { if (!ShowReadOnlyProperties) { return(null); } // If the property has no setter and it is an auto property, try and create a setter for its backing field instead var fld = GetGetterBackingField(propertyInfo); return(fld != null?CreateSetField(type, fld) : null); } var arguments = new Type[2]; arguments[0] = arguments[1] = typeof(object); var setter = new DynamicMethod("_csm", typeof(object), arguments, true); // !setMethod.IsPublic); // fix: skipverify var il = setter.GetILGenerator(); if (!type.IsClass) // structs { var lv = il.DeclareLocal(type); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Unbox_Any, type); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloca_S, lv); il.Emit(OpCodes.Ldarg_1); if (propertyInfo.PropertyType.IsClass) { il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); } else { il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); } il.EmitCall(OpCodes.Call, setMethod, null); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Box, type); } else { if (!setMethod.IsStatic) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); il.Emit(OpCodes.Ldarg_1); if (propertyInfo.PropertyType.IsClass) { il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); } else { il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); } il.EmitCall(OpCodes.Callvirt, setMethod, null); il.Emit(OpCodes.Ldarg_0); } else { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); if (propertyInfo.PropertyType.IsClass) { il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); } else { il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); } il.Emit(OpCodes.Call, setMethod); } } il.Emit(OpCodes.Ret); return((GenericSetter)setter.CreateDelegate(typeof(GenericSetter))); }
/// <summary> /// DataRow转换成Entity /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dr"></param> /// <returns></returns> public static T ToEntity <T>(DataRow dr) { var type = typeof(T); if (type == typeof(Int32) || type == typeof(Int64) || type == typeof(string)) { return((T)Convert.ChangeType(dr[0], type)); } StringBuilder key = new StringBuilder(); key.Append(type.Name + "_"); for (int index = 0; index < dr.Table.Columns.Count; index++) { key.Append(dr.Table.Columns[index].ColumnName); } var columns = EntityContext <T> .Columns; if (dr == null) { return(default(T)); } Convert <T> Converter = null; if (!Cache.ContainsKey(key.ToString())) { DynamicMethod method = new DynamicMethod(key.ToString(), type, new Type[] { typeof(DataRow) }, type, true); ILGenerator generator = method.GetILGenerator(); LocalBuilder result = generator.DeclareLocal(type); generator.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for (int index = 0; index < columns.Count; index++) { PropertyInfo propertyInfo = type.GetProperty(columns[index].ColumnName); Label endIfLabel = generator.DefineLabel(); if (dr.Table.Columns.Contains(propertyInfo.Name) && !columns[index].Ignore) { int rindex = dr.Table.Columns.IndexOf(propertyInfo.Name); if (rindex < 0) { continue; } //把参数推到堆栈中 generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, rindex); //dr.IsNull(rindex) generator.Emit(OpCodes.Callvirt, isDBNullMethod); generator.Emit(OpCodes.Brtrue, endIfLabel); //将指定索引处的局部变量加载到计算堆栈上。 generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, rindex); generator.Emit(OpCodes.Callvirt, getValueMethod); if (propertyInfo.PropertyType.IsValueType) { MethodInfo x = ConvertMethods[propertyInfo.PropertyType]; generator.Emit(OpCodes.Call, x); } else { if (propertyInfo.PropertyType == typeof(string)) { generator.Emit(OpCodes.Call, ConvertMethods[propertyInfo.PropertyType]); } else { if (propertyInfo.GetCustomAttribute(typeof(JsonNetAttribute)) != null) { var _normalmethod = typeof(JsonConvert).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == "DeserializeObject" && m.IsGenericMethod).FirstOrDefault(); MethodInfo _genericmethod = _normalmethod.MakeGenericMethod(new Type[] { propertyInfo.PropertyType }); generator.Emit(OpCodes.Call, _genericmethod); } else { generator.Emit(OpCodes.Castclass, propertyInfo.PropertyType); } } } generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); generator.MarkLabel(endIfLabel); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); Converter = (Convert <T>)method.CreateDelegate(typeof(Convert <T>)); //加锁 并发高时 出现插入键重复 lock (lockobj) { if (!Cache.ContainsKey(key.ToString())) { Cache.Add(key.ToString(), Converter); } } } else { Converter = (Convert <T>)Cache[key.ToString()]; } return(Converter(dr)); }
public Delegate GetDelegate() { if (m_impl != null) { return(m_impl); } MethodInfo method = m_delegateType.GetMethod("Invoke"); ParameterInfo[] parameters = method.GetParameters(); Type[] delegateParameters = new Type[parameters.Length + 1]; for (int i = 1; i <= parameters.Length; i++) { delegateParameters[i] = parameters[i - 1].ParameterType; } delegateParameters[0] = typeof(JsFunctionDelegate); DynamicMethod dm = new DynamicMethod( "DelegateWrapper", method.ReturnType, delegateParameters, typeof(JsFunctionDelegate) ); ILGenerator code = dm.GetILGenerator(); // arg_0 - this // arg_1 ... arg_n - delegate parameters // local_0 parameters // local_1 marshaller code.DeclareLocal(typeof(JsInstance[])); code.DeclareLocal(typeof(Marshaller)); // parameters = new JsInstance[...]; code.Emit(OpCodes.Ldc_I4, parameters.Length); code.Emit(OpCodes.Newarr, typeof(JsInstance)); code.Emit(OpCodes.Stloc_0); // load a marshller code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldfld, typeof(JsFunctionDelegate).GetField("m_marshaller", BindingFlags.NonPublic | BindingFlags.Instance)); code.Emit(OpCodes.Stloc_1); //code.EmitWriteLine("pre args"); for (int i = 1; i <= parameters.Length; i++) { ParameterInfo param = parameters[i - 1]; Type paramType = param.ParameterType; code.Emit(OpCodes.Ldloc_0); code.Emit(OpCodes.Ldc_I4, i - 1); // marshal arg code.Emit(OpCodes.Ldloc_1); code.Emit(OpCodes.Ldarg, i); // if parameter is passed by reference if (paramType.IsByRef) { paramType = paramType.GetElementType(); if (param.IsOut)// && !param.IsIn) // prop missing from silverlight, significance? { code.Emit(OpCodes.Ldarg, i); code.Emit(OpCodes.Initobj); } if (paramType.IsValueType) { code.Emit(OpCodes.Ldobj, paramType); } else { code.Emit(OpCodes.Ldind_Ref); } } code.Emit( OpCodes.Call, typeof(Marshaller) .GetMethod("MarshalClrValue") .MakeGenericMethod(paramType) ); // save arg code.Emit(OpCodes.Stelem, typeof(JsInstance)); } // m_visitor.ExecuteFunction(m_function,m_that,arguments) code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldfld, typeof(JsFunctionDelegate).GetField("m_visitor", BindingFlags.NonPublic | BindingFlags.Instance)); code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldfld, typeof(JsFunctionDelegate).GetField("m_function", BindingFlags.NonPublic | BindingFlags.Instance)); code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldfld, typeof(JsFunctionDelegate).GetField("m_that", BindingFlags.NonPublic | BindingFlags.Instance)); code.Emit(OpCodes.Ldloc_0); //params code.Emit(OpCodes.Callvirt, typeof(IJintVisitor).GetMethod("ExecuteFunction")); // foreach out parameter, marshal it back for (int i = 1; i <= parameters.Length; i++) { ParameterInfo param = parameters[i - 1]; Type paramType = param.ParameterType.GetElementType(); if (param.IsOut) { code.Emit(OpCodes.Ldarg, i); code.Emit(OpCodes.Ldloc_1); code.Emit(OpCodes.Ldloc_0); code.Emit(OpCodes.Ldc_I4, i - 1); code.Emit(OpCodes.Ldelem, typeof(JsInstance)); code.Emit(OpCodes.Call, typeof(Marshaller).GetMethod("MarshalJsValue").MakeGenericMethod(paramType)); if (paramType.IsValueType) { code.Emit(OpCodes.Stobj, paramType); } else { code.Emit(OpCodes.Stind_Ref); } } } // return marshaller.MarshalJsValue<method.ReturnType>(m_visitor.Returned) if (!method.ReturnType.Equals(typeof(void))) { code.Emit(OpCodes.Ldloc_1); code.Emit(OpCodes.Ldarg_0); code.Emit(OpCodes.Ldfld, typeof(JsFunctionDelegate).GetField("m_visitor", BindingFlags.NonPublic | BindingFlags.Instance)); code.Emit(OpCodes.Call, typeof(IJintVisitor).GetProperty("Returned").GetGetMethod()); code.Emit(OpCodes.Call, typeof(Marshaller).GetMethod("MarshalJsValue").MakeGenericMethod(method.ReturnType)); } code.Emit(OpCodes.Ret); return(m_impl = dm.CreateDelegate(m_delegateType, this)); }
private static Build CreateBuilder(Type destinationType, IDataRecord dataRecord) { Build builder; BuilderKey builderKey = new BuilderKey(destinationType, dataRecord); if (_builderCache.TryGetValue(builderKey, out builder)) { return(builder); } var method = new DynamicMethod("DynamicCreate", destinationType, new[] { typeof(IDataRecord) }, destinationType, true); var generator = method.GetILGenerator(); var result = generator.DeclareLocal(destinationType); generator.Emit(OpCodes.Newobj, destinationType.GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for (var i = 0; i < dataRecord.FieldCount; i++) { var propertyInfo = destinationType.GetProperty(dataRecord.GetName(i), BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance); var endIfLabel = generator.DefineLabel(); if (propertyInfo != null && propertyInfo.GetSetMethod(true) != null) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, isDBNullMethod); generator.Emit(OpCodes.Brtrue, endIfLabel); generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, getValueMethod); if (propertyInfo.PropertyType.IsGenericType && propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable <>)) ) { var nullableType = propertyInfo.PropertyType.GetGenericTypeDefinition().GetGenericArguments()[0]; if (!nullableType.IsEnum) { generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); } else { generator.Emit(OpCodes.Unbox_Any, nullableType); generator.Emit(OpCodes.Newobj, propertyInfo.PropertyType); } } else { generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i)); } generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod(true)); generator.MarkLabel(endIfLabel); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); builder = (Build)method.CreateDelegate(typeof(Build)); _builderCache[builderKey] = builder; return(builder); }
private void MakeReverseDelegateWorker(CodeContext context) { Type[] sigTypes; Type[] callSiteType; Type retType; GetSignatureInfo(out sigTypes, out callSiteType, out retType); DynamicMethod dm = new DynamicMethod("ReverseInteropInvoker", retType, ArrayUtils.RemoveLast(sigTypes), DynamicModule); ILGenerator ilGen = dm.GetILGenerator(); PythonContext pc = context.LanguageContext; Type callDelegateSiteType = CompilerHelpers.MakeCallSiteDelegateType(callSiteType); CallSite site = CallSite.Create(callDelegateSiteType, pc.Invoke(new CallSignature(_argtypes.Length))); List <object> constantPool = new List <object>(); constantPool.Add(null); // 1st item is the target object, will be put in later. constantPool.Add(site); ilGen.BeginExceptionBlock(); //CallSite<Func<CallSite, object, object>> mySite; //mySite.Target(mySite, target, ...); LocalBuilder siteLocal = ilGen.DeclareLocal(site.GetType()); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); ilGen.Emit(OpCodes.Ldelem_Ref); ilGen.Emit(OpCodes.Castclass, site.GetType()); ilGen.Emit(OpCodes.Stloc, siteLocal); ilGen.Emit(OpCodes.Ldloc, siteLocal); ilGen.Emit(OpCodes.Ldfld, site.GetType().GetField("Target")); ilGen.Emit(OpCodes.Ldloc, siteLocal); // load code context int contextIndex = constantPool.Count; Debug.Assert(pc.SharedContext != null); constantPool.Add(pc.SharedContext); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4, contextIndex); ilGen.Emit(OpCodes.Ldelem_Ref); // load function target, in constant pool slot 0 ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.Emit(OpCodes.Ldelem_Ref); // load arguments for (int i = 0; i < _argtypes.Length; i++) { INativeType nativeType = _argtypes[i]; nativeType.EmitReverseMarshalling(ilGen, new Arg(i + 1, sigTypes[i + 1]), constantPool, 0); } ilGen.Emit(OpCodes.Call, callDelegateSiteType.GetMethod("Invoke")); LocalBuilder finalRes = null; // emit forward marshaling for return value if (_restype != null) { LocalBuilder tmpRes = ilGen.DeclareLocal(typeof(object)); ilGen.Emit(OpCodes.Stloc, tmpRes); finalRes = ilGen.DeclareLocal(retType); ((INativeType)_restype).EmitMarshalling(ilGen, new Local(tmpRes), constantPool, 0); ilGen.Emit(OpCodes.Stloc, finalRes); } else { ilGen.Emit(OpCodes.Pop); } // } catch(Exception e) { // emit the cleanup code ilGen.BeginCatchBlock(typeof(Exception)); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4, contextIndex); ilGen.Emit(OpCodes.Ldelem_Ref); ilGen.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CallbackException")); ilGen.EndExceptionBlock(); if (_restype != null) { ilGen.Emit(OpCodes.Ldloc, finalRes); } ilGen.Emit(OpCodes.Ret); _reverseDelegateConstants = constantPool; _reverseDelegateType = GetReverseDelegateType(ArrayUtils.RemoveFirst(sigTypes), CallingConvention); _reverseDelegate = dm; }
/// <summary> /// Initializes a new <see cref="ReflectedMemberProperty{TContainer,TValue}"/> instance. This is an internal constructor. /// </summary> /// <param name="info">The reflected info object backing this property.</param> internal ReflectedMemberProperty(IMemberInfo info) { m_Info = info; m_IsStructContainerType = RuntimeTypeInfoCache <TContainer> .IsValueType; AddAttributes(info.GetCustomAttributes()); var isReadOnly = m_Info.IsReadOnly || HasAttribute <ReadOnlyAttribute>(); IsReadOnly = isReadOnly; if (m_Info is FieldMember fieldMember) { // TODO: optimize for NET_STANDARD, where DynamicMethod is not available by default #if NET_4_6 && !ENABLE_IL2CPP var fieldInfo = fieldMember.m_FieldInfo; // getter var dynamicMethod = new DynamicMethod(string.Empty, fieldInfo.FieldType, new Type[] { m_IsStructContainerType?fieldInfo.ReflectedType.MakeByRefType() : fieldInfo.ReflectedType }, true); var ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, fieldInfo); ilGenerator.Emit(OpCodes.Ret); if (m_IsStructContainerType) { m_GetStructValueAction = (GetStructValueAction)dynamicMethod.CreateDelegate(typeof(GetStructValueAction)); } else { m_GetClassValueAction = (GetClassValueAction)dynamicMethod.CreateDelegate(typeof(GetClassValueAction)); } // settter if (!isReadOnly) { dynamicMethod = new DynamicMethod(string.Empty, typeof(void), new Type[] { m_IsStructContainerType?fieldInfo.ReflectedType.MakeByRefType() : fieldInfo.ReflectedType, fieldInfo.FieldType }, true); ilGenerator = dynamicMethod.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stfld, fieldInfo); ilGenerator.Emit(OpCodes.Ret); if (m_IsStructContainerType) { m_SetStructValueAction = (SetStructValueAction)dynamicMethod.CreateDelegate(typeof(SetStructValueAction)); } else { m_SetClassValueAction = (SetClassValueAction)dynamicMethod.CreateDelegate(typeof(SetClassValueAction)); } } #endif } else if (m_Info is PropertyMember propertyMember) { if (m_IsStructContainerType) { var getMethod = propertyMember.m_PropertyInfo.GetGetMethod(true); m_GetStructValueAction = (GetStructValueAction)Delegate.CreateDelegate(typeof(GetStructValueAction), getMethod); if (!isReadOnly) { var setMethod = propertyMember.m_PropertyInfo.GetSetMethod(true); m_SetStructValueAction = (SetStructValueAction)Delegate.CreateDelegate(typeof(SetStructValueAction), setMethod); } } else { var getMethod = propertyMember.m_PropertyInfo.GetGetMethod(true); m_GetClassValueAction = (GetClassValueAction)Delegate.CreateDelegate(typeof(GetClassValueAction), getMethod); if (!isReadOnly) { var setMethod = propertyMember.m_PropertyInfo.GetSetMethod(true); m_SetClassValueAction = (SetClassValueAction)Delegate.CreateDelegate(typeof(SetClassValueAction), setMethod); } } } }
private static FastMethodHandler CreateMethodHandler(MethodInfo methodInfo) { DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module); ILGenerator il = dynamicMethod.GetILGenerator(); ParameterInfo[] ps = methodInfo.GetParameters(); Type[] paramTypes = new Type[ps.Length]; for (int i = 0; i < paramTypes.Length; i++) { if (ps[i].ParameterType.IsByRef) { paramTypes[i] = ps[i].ParameterType.GetElementType(); } else { paramTypes[i] = ps[i].ParameterType; } } LocalBuilder[] locals = new LocalBuilder[paramTypes.Length]; for (int i = 0; i < paramTypes.Length; i++) { locals[i] = il.DeclareLocal(paramTypes[i], true); } for (int i = 0; i < paramTypes.Length; i++) { il.Emit(OpCodes.Ldarg_1); EmitFastInt(il, i); il.Emit(OpCodes.Ldelem_Ref); EmitCastToReference(il, paramTypes[i]); il.Emit(OpCodes.Stloc, locals[i]); } if (!methodInfo.IsStatic) { il.Emit(OpCodes.Ldarg_0); } for (int i = 0; i < paramTypes.Length; i++) { if (ps[i].ParameterType.IsByRef) { il.Emit(OpCodes.Ldloca_S, locals[i]); } else { il.Emit(OpCodes.Ldloc, locals[i]); } } if (methodInfo.IsStatic) { il.EmitCall(OpCodes.Call, methodInfo, null); } else { il.EmitCall(OpCodes.Callvirt, methodInfo, null); } if (methodInfo.ReturnType == typeof(void)) { il.Emit(OpCodes.Ldnull); } else { EmitBoxIfNeeded(il, methodInfo.ReturnType); } for (int i = 0; i < paramTypes.Length; i++) { if (ps[i].ParameterType.IsByRef) { il.Emit(OpCodes.Ldarg_1); EmitFastInt(il, i); il.Emit(OpCodes.Ldloc, locals[i]); if (locals[i].LocalType.IsValueType) { il.Emit(OpCodes.Box, locals[i].LocalType); } il.Emit(OpCodes.Stelem_Ref); } } il.Emit(OpCodes.Ret); FastMethodHandler invoder = (FastMethodHandler)dynamicMethod.CreateDelegate(typeof(FastMethodHandler)); return(invoder); }
static Delegate CreateConstructorDelegate(ConstructorInfo constructor, Type delegateType) { if (constructor == null) { throw new ArgumentNullException(nameof(constructor)); } if (delegateType == null) { throw new ArgumentNullException(nameof(delegateType)); } MethodInfo delMethod = delegateType.GetMethod("Invoke"); //if (delMethod.ReturnType != constructor.DeclaringType) // throw new InvalidOperationException("The return type of the delegate must match the constructors delclaring type"); // Validate the signatures ParameterInfo[] delParams = delMethod.GetParameters(); ParameterInfo[] constructorParam = constructor.GetParameters(); if (delParams.Length != constructorParam.Length) { throw new InvalidOperationException("The delegate signature does not match that of the constructor"); } for (int i = 0; i < delParams.Length; i++) { if (delParams[i].ParameterType != constructorParam[i].ParameterType || // Probably other things we should check ?? delParams[i].IsOut) { throw new InvalidOperationException("The delegate signature does not match that of the constructor"); } } // Create the dynamic method DynamicMethod method = new DynamicMethod( string.Format("{0}__{1}", constructor.DeclaringType.Name, Guid.NewGuid().ToString().Replace("-", "")), constructor.DeclaringType, Array.ConvertAll <ParameterInfo, Type>(constructorParam, p => p.ParameterType), true ); // Create the il ILGenerator gen = method.GetILGenerator(); for (int i = 0; i < constructorParam.Length; i++) { if (i < 4) { switch (i) { case 0: gen.Emit(OpCodes.Ldarg_0); break; case 1: gen.Emit(OpCodes.Ldarg_1); break; case 2: gen.Emit(OpCodes.Ldarg_2); break; case 3: gen.Emit(OpCodes.Ldarg_3); break; } } else { gen.Emit(OpCodes.Ldarg_S, i); } } gen.Emit(OpCodes.Newobj, constructor); gen.Emit(OpCodes.Ret); return(method.CreateDelegate(delegateType)); }
/// <summary> /// Generate a new DynamicMethod with which you can invoke the previous state. /// If the NativeDetour holds a reference to a managed method, a copy of the original method is returned. /// If the NativeDetour holds a reference to a native function, an "undo-call-redo" trampoline with a matching signature is returned. /// </summary> public MethodBase GenerateTrampoline(MethodBase signature = null) { if (_IsFree) { throw new InvalidOperationException("Free() has been called on this detour."); } if (_BackupMethod != null) { // If we're detouring an IL method and have an IL copy, invoke the IL copy. // Note that this ignores the passed signature. return(_BackupMethod); } if (signature == null) { signature = _BackupMethod; } if (signature == null) { throw new ArgumentNullException("A signature must be given if the NativeDetour doesn't hold a reference to a managed method."); } // Otherwise, undo the detour, call the method and reapply the detour. MethodBase methodCallable = Method; if (methodCallable == null) { methodCallable = DetourManager.GenerateNativeProxy(Data.Method, signature); } Type returnType = (signature as MethodInfo)?.ReturnType ?? typeof(void); ParameterInfo[] args = signature.GetParameters(); Type[] argTypes = new Type[args.Length]; for (int i = 0; i < args.Length; i++) { argTypes[i] = args[i].ParameterType; } DynamicMethod dm; string name = $"trampoline_native_{Method?.Name.ToString() ?? ((long) Data.Method).ToString("X16")}_{GetHashCode()}"; if (Method != null) { dm = new DynamicMethod( name, returnType, argTypes, Method.DeclaringType, true ); } else { dm = new DynamicMethod( name, returnType, argTypes, true ); } ILGenerator il = dm.GetILGenerator(); il.EmitDetourCopy(_BackupNative, Data.Method, Data.Size); // Store the return value in a local as we can't preserve the stack across exception block boundaries. LocalBuilder localResult = null; if (returnType != typeof(void)) { localResult = il.DeclareLocal(returnType); } Label blockTry = il.BeginExceptionBlock(); // TODO: Use specialized Ldarg.* if possible; What about ref types? for (int i = 0; i < argTypes.Length; i++) { il.Emit(OpCodes.Ldarg, i); } if (methodCallable is MethodInfo) { il.Emit(OpCodes.Call, (MethodInfo)methodCallable); } else if (methodCallable is ConstructorInfo) { il.Emit(OpCodes.Call, (ConstructorInfo)methodCallable); } else { throw new NotSupportedException($"Method type {methodCallable.GetType().FullName} not supported."); } if (localResult != null) { il.Emit(OpCodes.Stloc_0); } il.BeginFinallyBlock(); // Reapply the detour even if the method threw an exception. il.EmitDetourApply(Data); il.EndExceptionBlock(); if (localResult != null) { il.Emit(OpCodes.Ldloc_0); } il.Emit(OpCodes.Ret); return(dm.Pin()); }
/// <summary> /// Generates a pure-IL nonbranching stream of instructions /// that perform the inverse DCT. Relies on helper function /// SetValueClipped. /// </summary> /// <returns>A delegate to the DynamicMethod</returns> private static IDCTFunc EmitIDCT() { Type[] args = { typeof(float[]), typeof(float[]), typeof(byte[, ]) }; DynamicMethod idctMethod = new DynamicMethod("dynamicIDCT", null, // no return type args); // input arrays ILGenerator il = idctMethod.GetILGenerator(); int idx = 0; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { il.Emit(OpCodes.Ldarg_1); // 1 {temp} il.Emit(OpCodes.Ldc_I4_S, (short)idx++); // 3 {temp, idx} for (int k = 0; k < 8; k++) { il.Emit(OpCodes.Ldarg_0); // {in} il.Emit(OpCodes.Ldc_I4_S, (short)(i * 8 + k)); // {in,idx} il.Emit(OpCodes.Ldelem_R4); // {in[idx]} il.Emit(OpCodes.Ldc_R4, c[k, j]); // {in[idx],c[k,j]} il.Emit(OpCodes.Mul); // {in[idx]*c[k,j]} if (k != 0) { il.Emit(OpCodes.Add); } } il.Emit(OpCodes.Stelem_R4); // {} } } var meth = typeof(DCT).GetMethod("SetValueClipped", BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Standard, new Type[] { typeof(byte[, ]), // arr typeof(int), // i typeof(int), // j typeof(float) } // val , null); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { il.Emit(OpCodes.Ldarg_2); // {output} il.Emit(OpCodes.Ldc_I4_S, (short)i); // {output,i} il.Emit(OpCodes.Ldc_I4_S, (short)j); // X={output,i,j} il.Emit(OpCodes.Ldc_R4, 128.0f); // {X,128.0f} for (int k = 0; k < 8; k++) { il.Emit(OpCodes.Ldarg_1); // {X,temp} il.Emit(OpCodes.Ldc_I4_S, (short)(k * 8 + j)); // {X,temp,idx} il.Emit(OpCodes.Ldelem_R4); // {X,temp[idx]} il.Emit(OpCodes.Ldc_R4, cT[i, k]); // {X,temp[idx],cT[i,k]} il.Emit(OpCodes.Mul); // {X,in[idx]*c[k,j]} il.Emit(OpCodes.Add); } il.EmitCall(OpCodes.Call, meth, null); } } il.Emit(OpCodes.Ret); return((IDCTFunc)idctMethod.CreateDelegate(typeof(IDCTFunc))); }
public MethodResult ExecuteMethod(DynamicMethod method, string parameterString) { object[] parameters = MethodRuleFactory.ToParamters(parameterString); return(new MethodResult(method, parameterString, ObjectUnderAnalyzsis.Invoke(method.MethodName, parameters))); }
private static Action <DataRow, T> GenerateFill() { var dynamicMethod = new DynamicMethod($"__Extensions__Fill__Of__{typeof(T).Name}", typeof(void), new[] { typeof(DataRow), typeof(T) }, typeof(T), true); var generator = dynamicMethod.GetILGenerator(); for (var i = 0; i < PropertyInfos.Length; i++) { generator.Emit(OpCodes.Ldarg_0); switch (i) { case 0: generator.Emit(OpCodes.Ldc_I4_0); break; case 1: generator.Emit(OpCodes.Ldc_I4_1); break; case 2: generator.Emit(OpCodes.Ldc_I4_2); break; case 3: generator.Emit(OpCodes.Ldc_I4_3); break; case 4: generator.Emit(OpCodes.Ldc_I4_4); break; case 5: generator.Emit(OpCodes.Ldc_I4_5); break; case 6: generator.Emit(OpCodes.Ldc_I4_6); break; case 7: generator.Emit(OpCodes.Ldc_I4_7); break; case 8: generator.Emit(OpCodes.Ldc_I4_8); break; default: if (i <= 127) { generator.Emit(OpCodes.Ldc_I4_S, (byte)i); } else { generator.Emit(OpCodes.Ldc_I4, i); } break; } generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Callvirt, PropertyInfos[i].GetGetMethod(true)); if (PropertyInfos[i].PropertyType.IsValueType) { generator.Emit(OpCodes.Box, PropertyInfos[i].PropertyType); } // ReSharper disable AssignNullToNotNullAttribute generator.Emit(OpCodes.Callvirt, typeof(DataRow).GetMethod("set_Item", new[] { typeof(int), typeof(object) })); // ReSharper restore AssignNullToNotNullAttribute } generator.Emit(OpCodes.Ret); return((Action <DataRow, T>)dynamicMethod.CreateDelegate(typeof(Action <DataRow, T>))); }
public DynamicResolver(DynamicMethod dynamicMethod, DynamicILInfo dynamicILInfo) { this.dynamicMethod = dynamicMethod; inst = factoryByDynamicILInfo(dynamicILInfo); }