public override JsonClassInfo.ConstructorDelegate CreateConstructor(Type type) { ConstructorInfo realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); //todo: verify json.net semantics if (realMethod == null) { return(null); // Exception will be raised later if called } var dynamicMethod = new DynamicMethod( realMethod.Name, type, Type.EmptyTypes, typeof(JsonReflectionEmitMaterializer).Module, skipVisibility: true); if (dynamicMethod == null) { throw new InvalidOperationException("todo - unable to create DynamicMethod"); } ILGenerator generator = dynamicMethod?.GetILGenerator(); if (generator == null) { throw new InvalidOperationException("todo - unable to create DynamicMethod"); } generator.Emit(OpCodes.Newobj, realMethod); generator.Emit(OpCodes.Ret); var result = (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate(typeof(JsonClassInfo.ConstructorDelegate)); return(result); }
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 override JsonPropertyInfo <TValue> .SetterDelegate CreateSetter <TValue>(PropertyInfo propertyInfo) { MethodInfo realMethod = propertyInfo.GetSetMethod(); Debug.Assert(realMethod != null); var dynamicMethod = new DynamicMethod( realMethod.Name, typeof(void), new Type[] { typeof(object), typeof(TValue) }, typeof(JsonReflectionEmitMaterializer).Module, skipVisibility: true); if (dynamicMethod != null) { ILGenerator generator = dynamicMethod?.GetILGenerator(); if (generator != null) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldarg_1); generator.EmitCall(OpCodes.Callvirt, realMethod, null); generator.Emit(OpCodes.Ret); var result = (JsonPropertyInfo <TValue> .SetterDelegate)dynamicMethod.CreateDelegate(typeof(JsonPropertyInfo <TValue> .SetterDelegate)); return(result); } } throw new InvalidOperationException(SR.Format(SR.SerializationUnableToCreateDynamicMethod, $"{propertyInfo.Name}.{realMethod.Name}")); }
public override JsonPropertyInfo <TValue> .GetterDelegate CreateGetter <TValue>(PropertyInfo propertyInfo) { MethodInfo realMethod = propertyInfo.GetGetMethod(); if (realMethod == null) { return(null); // Exception will be raised later if called } var dynamicMethod = new DynamicMethod( realMethod.Name, typeof(TValue), new Type[] { typeof(object) }, typeof(JsonReflectionEmitMaterializer).Module, skipVisibility: true); if (dynamicMethod == null) { throw new InvalidOperationException("todo - unable to create DynamicMethod"); } ILGenerator generator = dynamicMethod?.GetILGenerator(); if (generator == null) { throw new InvalidOperationException("todo - unable to create DynamicMethod"); } generator.Emit(OpCodes.Ldarg_0); generator.EmitCall(OpCodes.Callvirt, realMethod, null); generator.Emit(OpCodes.Ret); var result = (JsonPropertyInfo <TValue> .GetterDelegate)dynamicMethod.CreateDelegate(typeof(JsonPropertyInfo <TValue> .GetterDelegate)); return(result); }
public override JsonClassInfo.ConstructorDelegate CreateConstructor(Type type) { ConstructorInfo realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); if (realMethod == null) { return(null); } var dynamicMethod = new DynamicMethod( realMethod.Name, type, Type.EmptyTypes, typeof(JsonReflectionEmitMaterializer).Module, skipVisibility: true); if (dynamicMethod != null) { ILGenerator generator = dynamicMethod?.GetILGenerator(); if (generator != null) { generator.Emit(OpCodes.Newobj, realMethod); generator.Emit(OpCodes.Ret); var result = (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate(typeof(JsonClassInfo.ConstructorDelegate)); return(result); } } throw new InvalidOperationException(SR.Format(SR.SerializationUnableToCreateDynamicMethod, $"{type.FullName}.{realMethod.Name}")); }
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); }
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); }
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 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]); }
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 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 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 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); }
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; }
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 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)); }
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; }
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; }
/// <summary> /// Draws the property. /// </summary> protected override void DrawPropertyLayout(GUIContent label) { var entry = this.ValueEntry; var attribute = this.Attribute; var context = entry.Context.Get(this, "context", (Context)null); if (context.Value == null) { context.Value = new Context(); context.Value.MemberProperty = entry.Property.FindParent(p => p.Info.HasSingleBackingMember, true); var parentType = context.Value.MemberProperty.ParentType; var methodInfo = parentType .FindMember() .IsNamed(attribute.MethodName) .IsMethod() .HasReturnType <T>() .HasParameters <T, GUIContent>() .GetMember <MethodInfo>(out context.Value.ErrorMessage); if (context.Value.ErrorMessage == null) { if (methodInfo.IsStatic()) { context.Value.CustomValueDrawerStaticWithLabel = (Func <T, GUIContent, T>)Delegate.CreateDelegate(typeof(Func <T, GUIContent, T>), methodInfo); } else { DynamicMethod emittedMethod; emittedMethod = new DynamicMethod("CustomValueDrawerAttributeDrawer." + typeof(T).GetNiceFullName() + entry.Property.Path, typeof(T), new Type[] { typeof(object).MakeByRefType(), typeof(T), typeof(GUIContent) }, true); var il = emittedMethod.GetILGenerator(); if (parentType.IsValueType) { il.DeclareLocal(typeof(T)); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_Ref); il.Emit(OpCodes.Unbox_Any, parentType); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Ldloca_S, 0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Call, methodInfo); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Box, parentType); il.Emit(OpCodes.Stind_Ref); il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Ret); } else { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldind_Ref); il.Emit(OpCodes.Castclass, parentType); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Callvirt, methodInfo); il.Emit(OpCodes.Ret); } context.Value.CustomValueDrawerInstanceWithLabel = (InstanceDelegateWithLabel)emittedMethod.CreateDelegate(typeof(InstanceDelegateWithLabel)); } } } if (context.Value.ErrorMessage != null) { SirenixEditorGUI.ErrorMessageBox(context.Value.ErrorMessage); this.CallNextDrawer(label); } else { if (context.Value.CustomValueDrawerStaticWithLabel != null) { entry.SmartValue = context.Value.CustomValueDrawerStaticWithLabel(entry.SmartValue, label); } else { var val = context.Value.MemberProperty.ParentValues[0]; entry.SmartValue = context.Value.CustomValueDrawerInstanceWithLabel(ref val, entry.SmartValue, label); } } }
public DynamicMethod RecompileMethod(Cecil.MethodDefinition methodDef) { Debug.Trace("Recompiling method: {0}", methodDef.FullName); var declaringType = FindType(methodDef.DeclaringType); var returnType = FindType(methodDef.ReturnType); Type[] paramTypes = methodDef.Parameters.Select((paramDef) => { return(FindType(paramDef.ParameterType)); }).ToArray(); if (!methodDef.IsStatic) { paramTypes = new Type[] { declaringType }.Concat(paramTypes).ToArray(); } var dynMethod = new DynamicMethod(methodDef.Name, returnType, paramTypes, true); ILGenerator il = dynMethod.GetILGenerator(); dynMethod.InitLocals = methodDef.Body.InitLocals; foreach (var variable in methodDef.Body.Variables) { var localType = FindType(variable.VariableType); Debug.Trace("Declaring local (cecil type: {0}) of type (runtime type: {1})", variable.VariableType, localType); il.DeclareLocal(localType); } var labels = new Dictionary <Cecil.Cil.Instruction, Label>(); foreach (var inst in methodDef.Body.Instructions) { if (inst.Operand != null && inst.Operand.GetType() == typeof(Cecil.Cil.Instruction)) { var opinst = (Cecil.Cil.Instruction)(inst.Operand); labels[opinst] = il.DefineLabel(); } } foreach (var inst in Instrument.IterateInstructions(methodDef)) { Debug.Trace("Emitting: {0}", inst); Label label; if (labels.TryGetValue(inst, out label)) { il.MarkLabel(label); } var ilop = FindOpcode(inst.OpCode); if (inst.Operand == null) { // Simple operation without operand. il.Emit(ilop); continue; } var operand = inst.Operand; var operandType = operand.GetType(); // Dynamic dispatch implementation: // We have to run different processing code depending on the type of instruction // operand. Visitor pattern cannot be implemented here, because we don't actually // own the classes that are the operands (and some of them are primitive or system // types). // Therefore, dynamic dispatcher is used. Method for each operand type is implemented // in this class, and reflection is used to find correct method to call. // In newer .net versions we would be able to do EmitInstruction(il, ilop, (dynamic)operand), // but the .net version we are targeting (because of Unity compatibility) does not // have `dynamic`. if (operandType == typeof(Cecil.Cil.Instruction)) { //branch location var operandInst = (Cecil.Cil.Instruction)operand; il.Emit(ilop, labels[operandInst]); } else if (primitiveOperandTypes.Contains(operandType)) { //if operand is primitive, call il.Emit directly Reflection.MethodInfo method; if (!EmitPrimitiveCache.TryGetValue(operandType, out method)) { method = typeof(ILGenerator).GetMethod("Emit", new Type[] { typeof(OpCode), operandType }); EmitPrimitiveCache[operandType] = method; } if (method == null) { throw new Exception(String.Format("Emit method for primitive type {0} not found.", operandType.Name)); } try { method.Invoke(il, new object[] { ilop, operand }); } catch (Reflection.TargetInvocationException e) { throw e.InnerException; } } else { //or else, call our EmitInstruction Reflection.MethodInfo method; if (!EmitInstructionCache.TryGetValue(operandType, out method)) { method = GetType().GetMethod("EmitInstruction", bindingAttr: bflags_all_instance, binder: null, modifiers: null, types: new Type[] { typeof(ILGenerator), typeof(OpCode), operandType }); EmitInstructionCache[operandType] = method; } if (method == null) { throw new Exception(String.Format("Don't know what to do with operand {0}", operandType.Name)); } try { method.Invoke(this, new object[] { il, ilop, operand }); } catch (Reflection.TargetInvocationException e) { throw e.InnerException; } } } return(dynMethod); }
void init(PropertyInfo property) { if (property == null) { throw new ArgumentException("Argument: property is null"); } var getmethod = property.GetGetMethod(); var setmethod = property.GetSetMethod(); //PropertyGet = new DelegateMethodInvoker(property.GetGetMethod()); //PropertySet = new DelegateMethodInvoker(property.GetSetMethod()); var name = ReflectionHelper.GetMemberSignName(property); var type = property.DeclaringType; if (getmethod != null && !getmethod.IsPublic) { PropertyGet = obj => property.GetValue(obj, null); } else { DynamicMethod method = new DynamicMethod(name + "_get", ReflectionHelper.ObjectType, new Type[] { ReflectionHelper.ObjectType }); var il = method.GetILGenerator(); if (getmethod != null) { ReflectionHelper.ILLdarg(il, 0); ReflectionHelper.ILCastclass(il, ReflectionHelper.ObjectType, type); il.Emit(OpCodes.Callvirt, getmethod); ReflectionHelper.ILCastclass(il, property.PropertyType, ReflectionHelper.ObjectType); il.Emit(OpCodes.Ret); } else { ReflectionHelper.ILThrow <MethodAccessException>(il, "get method not found"); } PropertyGet = (Func <object, object>)method.CreateDelegate(typeof(Func <object, object>)); } if (setmethod != null && !setmethod.IsPublic) { PropertySet = (obj, val) => property.SetValue(obj, val, null); } else { DynamicMethod method = new DynamicMethod(name + "_set", ReflectionHelper.VoidType, new Type[] { ReflectionHelper.ObjectType, ReflectionHelper.ObjectType }); var il = method.GetILGenerator(); if (setmethod != null) { ReflectionHelper.ILLdarg(il, 0); ReflectionHelper.ILCastclass(il, ReflectionHelper.ObjectType, type); ReflectionHelper.ILLdarg(il, 1); ReflectionHelper.ILCastclass(il, ReflectionHelper.ObjectType, property.PropertyType); il.Emit(OpCodes.Callvirt, setmethod); il.Emit(OpCodes.Ret); } else { ReflectionHelper.ILThrow <MethodAccessException>(il, "set method not found"); } PropertySet = (Action <object, object>)method.CreateDelegate(typeof(Action <object, object>)); } }
public void Emit_UnknownOpCodeWithMethodInfo_ThrowsNotSupportedException() { DynamicMethod dynamicMethod = new DynamicMethod(typeof(object), new Type[] { typeof(object[]) }); ILGenerator generator = dynamicMethod.GetILGenerator(); Assert.Throws<NotSupportedException>(() => generator.Emit(OpCodes.Add, (MethodInfo)null)); }
/// <summary> /// Generates an eventhandler for an event of type eventSignature that calls RegisterEvent on recorder /// when invoked. /// </summary> public static Delegate GenerateHandler(Type eventSignature, EventRecorder recorder) { Type returnType = GetDelegateReturnType(eventSignature); Type[] parameters = GetDelegateParameterTypes(eventSignature); Module module = recorder.GetType() .Module; var eventHandler = new DynamicMethod( eventSignature.Name + "DynamicHandler", returnType, AppendParameterListThisReference(parameters), module); MethodInfo methodToCall = typeof(EventRecorder).GetMethod(nameof(EventRecorder.RecordEvent), BindingFlags.Instance | BindingFlags.Public); ILGenerator ilGen = eventHandler.GetILGenerator(); // Make room for the one and only local variable in our function ilGen.DeclareLocal(typeof(object[])); // Create the object array for the parameters and store in local var index 0 ilGen.Emit(OpCodes.Ldc_I4, parameters.Length); ilGen.Emit(OpCodes.Newarr, typeof(object)); ilGen.Emit(OpCodes.Stloc_0); for (var index = 0; index < parameters.Length; index++) { // Push the object array onto the evaluation stack ilGen.Emit(OpCodes.Ldloc_0); // Push the array index to store our parameter in onto the evaluation stack ilGen.Emit(OpCodes.Ldc_I4, index); // Load the parameter ilGen.Emit(OpCodes.Ldarg, index + 1); // Box value-type parameters if (parameters[index].IsValueType) { ilGen.Emit(OpCodes.Box, parameters[index]); } // Store the parameter in the object array ilGen.Emit(OpCodes.Stelem_Ref); } // Push the this-reference on the stack as param 0 for calling the handler ilGen.Emit(OpCodes.Ldarg_0); // Push the object array onto the stack as param 1 for calling the handler ilGen.Emit(OpCodes.Ldloc_0); // Call the handler ilGen.EmitCall(OpCodes.Callvirt, methodToCall, null); ilGen.Emit(OpCodes.Ret); return(eventHandler.CreateDelegate(eventSignature, recorder)); }
public DynamicMethod GetDM () { List<Type> parms = new List<Type>(); parms.Add(typeof(object)); foreach (DTypeInfo dti in Parameters) parms.Add(dti.ToType()); DynamicMethod dm = new DynamicMethod (Name, ReturnType.ToType(), parms.ToArray(), typeof(DemoBase)); ILGenerator ilg = dm.GetILGenerator(); Implement(ilg); return dm; }
private static Action <IDbCommand> GetInit(Type commandType) { if (commandType == null) { return(null); } if (commandInitCache.TryGetValue(commandType, out Action <IDbCommand> value)) { return(value); } MethodInfo basicPropertySetter = GetBasicPropertySetter(commandType, "BindByName", typeof(bool)); MethodInfo basicPropertySetter2 = GetBasicPropertySetter(commandType, "InitialLONGFetchSize", typeof(int)); if (basicPropertySetter != null || basicPropertySetter2 != null) { #if NETSTANDARD2_0_OR_GREATER /* * (IDbCommand cmd) => { * (OracleCommand)cmd.set_BindByName(true); * (OracleCommand)cmd.set_InitialLONGFetchSize(-1); * } */ ParameterExpression cmdExp = Expression.Parameter(typeof(IDbCommand), "cmd"); List <Expression> body = new List <Expression>(); if (basicPropertySetter != null) { UnaryExpression convertedCmdExp = Expression.Convert(cmdExp, commandType); MethodCallExpression setter1Exp = Expression.Call(convertedCmdExp, basicPropertySetter, Expression.Constant(true, typeof(bool))); body.Add(setter1Exp); } if (basicPropertySetter2 != null) { UnaryExpression convertedCmdExp = Expression.Convert(cmdExp, commandType); MethodCallExpression setter2Exp = Expression.Call(convertedCmdExp, basicPropertySetter2, Expression.Constant(-1, typeof(int))); body.Add(setter2Exp); } var lambda = Expression.Lambda <Action <IDbCommand> >(Expression.Block(body), cmdExp); value = lambda.Compile(); #else DynamicMethod dynamicMethod = new DynamicMethod(commandType.Name + "_init", null, new Type[1] { typeof(IDbCommand) }); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); if (basicPropertySetter != null) { iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Castclass, commandType); iLGenerator.Emit(OpCodes.Ldc_I4_1); iLGenerator.EmitCall(OpCodes.Callvirt, basicPropertySetter, null); } if (basicPropertySetter2 != null) { iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Castclass, commandType); iLGenerator.Emit(OpCodes.Ldc_I4_M1); iLGenerator.EmitCall(OpCodes.Callvirt, basicPropertySetter2, null); } iLGenerator.Emit(OpCodes.Ret); value = (Action <IDbCommand>)dynamicMethod.CreateDelegate(typeof(Action <IDbCommand>)); #endif commandInitCache.Add(commandType, value); } return(value); }
private Delegate createDynamicWrapper(object target, Type delegateType, ParameterInfo[] eventParams, MethodInfo eventHandler) { Type[] array = ((IEnumerable<Type>)(new Type[] { target.GetType() })).Concat<Type>( from p in (IEnumerable<ParameterInfo>)eventParams select p.ParameterType).ToArray<Type>(); DynamicMethod dynamicMethod = new DynamicMethod(string.Concat("DynamicEventWrapper_", eventHandler.Name), typeof(void), array); ILGenerator lGenerator = dynamicMethod.GetILGenerator(); lGenerator.Emit(OpCodes.Ldarg_0); lGenerator.EmitCall(OpCodes.Callvirt, eventHandler, Type.EmptyTypes); lGenerator.Emit(OpCodes.Ret); return dynamicMethod.CreateDelegate(delegateType, target); }
private static Func <IDataReader, M> SetFunc(IDataReader reader) { // var mType = typeof(M); var dm = new DynamicMethod("MyDAL" + Guid.NewGuid().ToString(), mType, new[] { typeof(IDataReader) }, mType, true); var il = dm.GetILGenerator(); il.DeclareLocal(typeof(int)); // 定义 loc0 int il.DeclareLocal(mType); // 定义 loc1 M il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc_0); // 赋值 loc0 = 0 // var length = reader.FieldCount; var names = Enumerable.Range(0, length).Select(i => reader.GetName(i)).ToArray(); var typeMap = CommonIL.GetTypeMap(mType); int index = 0; var ctor = typeMap.DefaultConstructor(); // il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Stloc_1); // 赋值 loc1 = new M(); il.BeginExceptionBlock(); // try begin il.Emit(OpCodes.Ldloc_1); // 加载 loc1 // var members = names.Select(n => typeMap.GetMember(n)).ToList(); //bool first = true; var allDone = il.DefineLabel(); int enumDeclareLocal = -1; int valueCopyLocal = il.DeclareLocal(typeof(object)).LocalIndex; // 定义 loc_object 变量, 然后返回此本地变量的index值, 其实就是截止目前, 定义了本地变量的个数 foreach (var item in members) { if (item != null) { il.Emit(OpCodes.Dup); Label isDbNullLabel = il.DefineLabel(); Label finishLabel = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); CommonIL.EmitInt32(il, index); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Callvirt, XConfig.GetItem); // 获取reader读取的值, reader[index] il.Emit(OpCodes.Dup); CommonIL.StoreLocal(il, valueCopyLocal); // 将 reader[index]的值, 存放到本地变量 loc_object 中 Type colType = reader.GetFieldType(index); // reader[index] 的列的类型 source Type memberType = item.MemberType(); // M[item] 的类型 if (memberType == XConfig.CSTC.Char || memberType == XConfig.CSTC.CharNull) { il.EmitCall( OpCodes.Call, typeof(CommonIL).GetMethod( memberType == XConfig.CSTC.Char ? nameof(CommonIL.ReadChar) : nameof(CommonIL.ReadNullableChar), BindingFlags.Static | BindingFlags.NonPublic), null); } else { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Isinst, typeof(DBNull)); // 判断是否为DBNull类型, 如果是, 则跳转到 标签isDbNullLabel il.Emit(OpCodes.Brtrue_S, isDbNullLabel); var nullUnderlyingType = Nullable.GetUnderlyingType(memberType); var unboxType = nullUnderlyingType?.IsEnum == true ? nullUnderlyingType : memberType; if (unboxType.IsEnum) { Type numericType = Enum.GetUnderlyingType(unboxType); if (colType == typeof(string)) { if (enumDeclareLocal == -1) { enumDeclareLocal = il.DeclareLocal(typeof(string)).LocalIndex; } il.Emit(OpCodes.Castclass, typeof(string)); // stack is now [target][target][string] CommonIL.StoreLocal(il, enumDeclareLocal); // stack is now [target][target] il.Emit(OpCodes.Ldtoken, unboxType); // stack is now [target][target][enum-type-token] il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)), null); // stack is now [target][target][enum-type] CommonIL.LoadLocal(il, enumDeclareLocal); // stack is now [target][target][enum-type][string] il.Emit(OpCodes.Ldc_I4_1); // stack is now [target][target][enum-type][string][true] il.EmitCall(OpCodes.Call, XConfig.EnumParse, null); // stack is now [target][target][enum-as-object] il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value] } else { CommonIL.FlexibleConvertBoxedFromHeadOfStack(il, colType, unboxType, numericType); } if (nullUnderlyingType != null) { il.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType })); // stack is now [target][target][typed-value] } } else if (memberType.FullName == XConfig.CSTC.LinqBinary) { il.Emit(OpCodes.Unbox_Any, typeof(byte[])); // stack is now [target][target][byte-array] il.Emit(OpCodes.Newobj, memberType.GetConstructor(new Type[] { typeof(byte[]) })); // stack is now [target][target][binary] } else { TypeCode dataTypeCode = Type.GetTypeCode(colType), unboxTypeCode = Type.GetTypeCode(unboxType); if (colType == unboxType || dataTypeCode == unboxTypeCode || dataTypeCode == Type.GetTypeCode(nullUnderlyingType)) { il.Emit(OpCodes.Unbox_Any, unboxType); // stack is now [target][target][typed-value] } else { // not a direct match; need to tweak the unbox CommonIL.FlexibleConvertBoxedFromHeadOfStack(il, colType, nullUnderlyingType ?? unboxType, null); if (nullUnderlyingType != null) { il.Emit(OpCodes.Newobj, unboxType.GetConstructor(new[] { nullUnderlyingType })); // stack is now [target][target][typed-value] } } } } // Store the value in the property/field if (item.Property != null) { il.Emit(OpCodes.Callvirt, RowMap.GetPropertySetter(item.Property, mType)); } else { il.Emit(OpCodes.Stfld, item.Field); // 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); } //first = false; index++; } il.Emit(OpCodes.Stloc_1); // stack is empty il.MarkLabel(allDone); il.BeginCatchBlock(typeof(Exception)); // stack is Exception il.Emit(OpCodes.Ldloc_0); // stack is Exception, index il.Emit(OpCodes.Ldarg_0); // stack is Exception, index, reader CommonIL.LoadLocal(il, valueCopyLocal); // stack is Exception, index, reader, value il.EmitCall(OpCodes.Call, typeof(CommonIL).GetMethod(nameof(CommonIL.ThrowDataException)), null); il.EndExceptionBlock(); il.Emit(OpCodes.Ldloc_1); // stack is [rval] il.Emit(OpCodes.Ret); var funcType = Expression.GetFuncType(typeof(IDataReader), mType); return((Func <IDataReader, M>)dm.CreateDelegate(funcType)); }
public static DynamicMethodDelegate CreateDelegate(this MethodBase method) { var dynam = new DynamicMethod(string.Empty, typeof(object), _ManyObjects, typeof(ReflectionHelper).Module, true); ILGenerator il = dynam.GetILGenerator(); ParameterInfo[] args = method.GetParameters(); Label argsOK = il.DefineLabel(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldlen); il.Emit(OpCodes.Ldc_I4, args.Length); il.Emit(OpCodes.Beq, argsOK); il.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(Type.EmptyTypes)); il.Emit(OpCodes.Throw); il.MarkLabel(argsOK); if (!method.IsStatic && !method.IsConstructor) { il.Emit(OpCodes.Ldarg_0); if (method.DeclaringType.IsValueType) { il.Emit(OpCodes.Unbox, method.DeclaringType); } } for (int i = 0; i < args.Length; i++) { il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldelem_Ref); if (args[i].ParameterType.IsValueType) { il.Emit(OpCodes.Unbox_Any, args[i].ParameterType); } } if (method.IsConstructor) { il.Emit(OpCodes.Newobj, (ConstructorInfo)method); } else if (method.IsFinal || !method.IsVirtual) { il.Emit(OpCodes.Call, (MethodInfo)method); } else { il.Emit(OpCodes.Callvirt, (MethodInfo)method); } Type returnType = method.IsConstructor ? method.DeclaringType : ((MethodInfo)method).ReturnType; if (returnType != typeof(void)) { if (returnType.IsValueType) { il.Emit(OpCodes.Box, returnType); } } else { il.Emit(OpCodes.Ldnull); } il.Emit(OpCodes.Ret); return((DynamicMethodDelegate)dynam.CreateDelegate(typeof(DynamicMethodDelegate))); }
// Create factory function that can convert a IDataReader record into a POCO public Delegate GetFactory(string sql, string connectionString, int firstColumn, int countColumns, IDataReader reader, IMapper defaultMapper) { // Check cache var key = Tuple.Create <string, string, int, int>(sql, connectionString, 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, defaultMapper); 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 = reader.GetFieldType(i); il.Emit(OpCodes.Dup); // obj, obj il.Emit(OpCodes.Ldstr, reader.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 if (Type.IsValueType || Type == typeof(string) || Type == typeof(byte[])) { // Do we need to install a converter? var srcType = reader.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() var ctor = Type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null); if (ctor == null) { throw new InvalidOperationException("Type [" + Type.FullName + "] should have default public or non-public constructor"); } il.Emit(OpCodes.Newobj, ctor); // 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(reader.GetName(i), out pc)) { continue; } // Get the source type for this column var srcType = reader.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)); } )); }
private static Func <LightLambda, Delegate> MakeRunDelegateCtor(Type delegateType) { var method = delegateType.GetMethod("Invoke"); var paramInfos = method.GetParameters(); Type[] paramTypes; string name = "Run"; if (paramInfos.Length >= MaxParameters) { return(null); } if (method.ReturnType == typeof(void)) { name += "Void"; paramTypes = new Type[paramInfos.Length]; } else { paramTypes = new Type[paramInfos.Length + 1]; paramTypes[paramTypes.Length - 1] = method.ReturnType; } MethodInfo runMethod; if (method.ReturnType == typeof(void) && paramTypes.Length == 2 && paramInfos[0].ParameterType.IsByRef && paramInfos[1].ParameterType.IsByRef) { runMethod = typeof(LightLambda).GetMethod("RunVoidRef2", BindingFlags.NonPublic | BindingFlags.Instance); paramTypes[0] = paramInfos[0].ParameterType.GetElementType(); paramTypes[1] = paramInfos[1].ParameterType.GetElementType(); } else if (method.ReturnType == typeof(void) && paramTypes.Length == 0) { runMethod = typeof(LightLambda).GetMethod("RunVoid0", BindingFlags.NonPublic | BindingFlags.Instance); } else { for (int i = 0; i < paramInfos.Length; i++) { paramTypes[i] = paramInfos[i].ParameterType; if (paramTypes[i].IsByRef) { return(null); } } if (DelegateHelpers.MakeDelegate(paramTypes) == delegateType) { name = "Make" + name + paramInfos.Length; MethodInfo ctorMethod = typeof(LightLambda).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(paramTypes); return(_runCache[delegateType] = (Func <LightLambda, Delegate>)Delegate.CreateDelegate(typeof(Func <LightLambda, Delegate>), ctorMethod)); } runMethod = typeof(LightLambda).GetMethod(name + paramInfos.Length, BindingFlags.NonPublic | BindingFlags.Instance); } #if !SILVERLIGHT try { DynamicMethod dm = new DynamicMethod("FastCtor", typeof(Delegate), new[] { typeof(LightLambda) }, typeof(LightLambda), true); var ilgen = dm.GetILGenerator(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Ldftn, runMethod.IsGenericMethodDefinition ? runMethod.MakeGenericMethod(paramTypes) : runMethod); ilgen.Emit(OpCodes.Newobj, delegateType.GetConstructor(new[] { typeof(object), typeof(IntPtr) })); ilgen.Emit(OpCodes.Ret); return(_runCache[delegateType] = (Func <LightLambda, Delegate>)dm.CreateDelegate(typeof(Func <LightLambda, Delegate>))); } catch (SecurityException) { } #endif // we don't have permission for restricted skip visibility dynamic methods, use the slower Delegate.CreateDelegate. var targetMethod = runMethod.IsGenericMethodDefinition ? runMethod.MakeGenericMethod(paramTypes) : runMethod; return(_runCache[delegateType] = lambda => Delegate.CreateDelegate(delegateType, lambda, targetMethod)); }
/// <summary> /// Performs a non-virtual (non-polymorphic) call to the given <paramref name="method"/> /// using the specified object <paramref name="instance"/> and <paramref name="arguments"/>. /// </summary> public static object DynamicInvokeNonVirtually( MethodInfo method, object instance, object[] arguments ) { // There are a couple of probable alternatives to the following implementation that // unfortunately don't work in practice: // // * We could try `method.Invoke(instance, InvokeMethod | DeclaredOnly, arguments)`, // unfortunately that doesn't work. `DeclaredOnly` does not have the desired effect. // // * We could get a function pointer via `method.MethodHandle.GetFunctionPointer()`, // then construct a delegate for it (see ECMA-335 ?II.14.4). This does not work // because the delegate signature would have to have a matching parameter list, // not just an untyped `object[]`. It also doesn't work because we don't always have // a suitable delegate type ready (e.g. when a method has by-ref parameters). // // So we end up having to create a dynamic method that transforms the `object[]`array // to a properly typed argument list and then invokes the method using the IL `call` // instruction. var thunk = nonVirtualInvocationThunks.GetOrAdd( method, static method => { var originalParameterTypes = method.GetParameterTypes(); var n = originalParameterTypes.Count; var dynamicMethod = new DynamicMethod( string.Empty, returnType: typeof(object), parameterTypes: new[] { typeof(object), typeof(object[]) } ); dynamicMethod.InitLocals = true; var il = dynamicMethod.GetILGenerator(); var arguments = new LocalBuilder[n]; var returnValue = il.DeclareLocal(typeof(object)); // Erase by-ref-ness of parameter types to get at the actual type of value. // We need this because we are handed `invocation.Arguments` as an `object[]` array. var parameterTypes = originalParameterTypes.ToArray(); for (var i = 0; i < n; ++i) { if (parameterTypes[i].IsByRef) { parameterTypes[i] = parameterTypes[i].GetElementType(); } } // Transfer `invocation.Arguments` into appropriately typed local variables. // This involves unboxing value-typed arguments, and possibly down-casting others from `object`. // The `unbox.any` instruction will do the right thing in both cases. for (var i = 0; i < n; ++i) { arguments[i] = il.DeclareLocal(parameterTypes[i]); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Unbox_Any, parameterTypes[i]); il.Emit(OpCodes.Stloc, arguments[i]); } // Now we're going to call the actual default implementation. // We do this inside a `try` block because we need to write back possibly modified // arguments to `invocation.Arguments` even if the called method throws. var returnLabel = il.DefineLabel(); il.BeginExceptionBlock(); // Perform the actual call. il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, method.DeclaringType); for (var i = 0; i < n; ++i) { il.Emit( originalParameterTypes[i].IsByRef ? OpCodes.Ldloca : OpCodes.Ldloc, arguments[i] ); } il.Emit(OpCodes.Call, method); // Put the return value in a local variable for later retrieval. if (method.ReturnType != typeof(void)) { il.Emit(OpCodes.Box, method.ReturnType); il.Emit(OpCodes.Castclass, typeof(object)); il.Emit(OpCodes.Stloc, returnValue); } il.Emit(OpCodes.Leave, returnLabel); il.BeginFinallyBlock(); // Write back possibly modified arguments to `invocation.Arguments`. for (var i = 0; i < n; ++i) { il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Ldloc, arguments[i]); il.Emit(OpCodes.Box, arguments[i].LocalType); il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Endfinally); il.EndExceptionBlock(); il.MarkLabel(returnLabel); il.Emit(OpCodes.Ldloc, returnValue); il.Emit(OpCodes.Ret); return((Func <object, object[], object>) dynamicMethod.CreateDelegate(typeof(Func <object, object[], object>))); } ); return(thunk.Invoke(instance, arguments)); }
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; }
public void CreateDelegate_InvalidTarget_ThrowsArgumentException() { 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); Assert.Throws<ArgumentException>(null, () => method.CreateDelegate(typeof(IntDelegate), "foo")); }
public static void Main() { // Create an array that specifies the types of the parameters // of the dynamic method. This dynamic method has a String // parameter and an Integer parameter. Type[] helloArgs = {typeof(string), typeof(int), typeof(int)}; // Create a dynamic method with the name "Hello", a return type // of Integer, and two parameters whose types are specified by // the array helloArgs. Create the method in the module that // defines the String class. DynamicMethod hello = new DynamicMethod("Hello", typeof(int), helloArgs, typeof(string).Module); // Create an array that specifies the parameter types of the // overload of Console.WriteLine to be used in Hello. Type[] writeStringArgs = {typeof(string)}; // Get the overload of Console.WriteLine that has one // String parameter. MethodInfo writeString = typeof(Console).GetMethod("WriteLine", writeStringArgs); // Get an ILGenerator and emit a body for the dynamic method, // using a stream size larger than the IL that will be // emitted. ILGenerator il = hello.GetILGenerator(256); // Load the first argument, which is a string, onto the stack. il.Emit(OpCodes.Ldarg_0); // Call the overload of Console.WriteLine that prints a string. il.EmitCall(OpCodes.Call, writeString, null); // The Hello method returns the value of the second argument; // to do this, load the onto the stack and return. il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldc_I4_X, 1337); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ret); // Add parameter information to the dynamic method. (This is not // necessary, but can be useful for debugging.) For each parameter, // identified by position, supply the parameter attributes and a // parameter name. hello.DefineParameter(1, ParameterAttributes.In, "message"); hello.DefineParameter(2, ParameterAttributes.In, "valueToReturn"); // Create a delegate that represents the dynamic method. This // action completes the method. Any further attempts to // change the method are ignored. HelloDelegate hi = (HelloDelegate) hello.CreateDelegate(typeof(HelloDelegate)); // Use the delegate to execute the dynamic method. Console.WriteLine("\r\nUse the delegate to execute the dynamic method:"); int retval = hi("\r\nHello, World!", 42, 30); Console.WriteLine("Invoking delegate hi(\"Hello, World!\", 42, 30) returned: " + retval); // Execute it again, with different arguments. retval = hi("\r\nHi, Mom!", 5280, 37); Console.WriteLine("Invoking delegate hi(\"Hi, Mom!\", 5280, 37) returned: " + retval); Console.WriteLine("\r\nUse the Invoke method to execute the dynamic method:"); // Create an array of arguments to use with the Invoke method. object[] invokeArgs = {"\r\nHello, World!", 42, 30}; // Invoke the dynamic method using the arguments. This is much // slower than using the delegate, because you must create an // array to contain the arguments, and value-type arguments // must be boxed. object objRet = hello.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new CultureInfo("en-us")); Console.WriteLine("hello.Invoke returned: " + objRet); Console.WriteLine("\r\n ----- Display information about the dynamic method -----"); // Display MethodAttributes for the dynamic method, set when // the dynamic method was created. Console.WriteLine("\r\nMethod Attributes: {0}", hello.Attributes); // Display the calling convention of the dynamic method, set when the // dynamic method was created. Console.WriteLine("\r\nCalling convention: {0}", hello.CallingConvention); // Display the declaring type, which is always null for dynamic // methods. if (hello.DeclaringType == null) { Console.WriteLine("\r\nDeclaringType is always null for dynamic methods."); } else { Console.WriteLine("DeclaringType: {0}", hello.DeclaringType); } // Display the default value for InitLocals. if (hello.InitLocals) { Console.Write("\r\nThis method contains verifiable code."); } else { Console.Write("\r\nThis method contains unverifiable code."); } Console.WriteLine(" (InitLocals = {0})", hello.InitLocals); // Display the module specified when the dynamic method was created. Console.WriteLine("\r\nModule: {0}", hello.Module); // Display the name specified when the dynamic method was created. // Note that the name can be blank. Console.WriteLine("\r\nName: {0}", hello.Name); // For dynamic methods, the reflected type is always null. if (hello.ReflectedType == null) { Console.WriteLine("\r\nReflectedType is null."); } else { Console.WriteLine("\r\nReflectedType: {0}", hello.ReflectedType); } //beyond scope of project // if (hello.ReturnParameter == null) // { // Console.WriteLine("\r\nMethod has no return parameter."); // } // else // { // Console.WriteLine("\r\nReturn parameter: {0}", hello.ReturnParameter); // } // If the method has no return type, ReturnType is System.Void. Console.WriteLine("\r\nReturn type: {0}", hello.ReturnType); // ReturnTypeCustomAttributes returns an ICustomeAttributeProvider // that can be used to enumerate the custom attributes of the // return value. At present, there is no way to set such custom // attributes, so the list is empty. //beyond scope of project // if (hello.ReturnType == typeof(void)) // { // Console.WriteLine("The method has no return type."); // } // else // { // ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes; // object[] returnAttributes = caProvider.GetCustomAttributes(true); // if (returnAttributes.Length == 0) // { // Console.WriteLine("\r\nThe return type has no custom attributes."); // } // else // { // Console.WriteLine("\r\nThe return type has the following custom attributes:"); // foreach( object attr in returnAttributes ) // { // Console.WriteLine("\t{0}", attr.ToString()); // } // } // } Console.WriteLine("\r\nToString: {0}", hello.ToString()); Console.WriteLine("\r\nToString: {0}", hello.ToString()); // Display parameter information. ParameterInfo[] parameters = hello.GetParameters(); Console.WriteLine("\r\nParameters: name, type, ParameterAttributes"); foreach( ParameterInfo p in parameters ) { Console.WriteLine("\t{0}, {1}, {2}", p.Name, p.ParameterType, p.Attributes); } Console.WriteLine("array assignment"); Type[] paramTypes = { typeof(uint), typeof(string), typeof(string), typeof(uint) }; Console.WriteLine(paramTypes[1]); }
/// <summary> /// Constructs a new method emitter. /// </summary> /// <param name="method">The desired internal method.</param> public MethodEmitter( DynamicMethod method) { Method = method; ILGenerator = method.GetILGenerator(); }
internal static InstantiateObjectHandler CreateInstantiateObjectHandler(Type type) { ConstructorInfo constructorInfo = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null); if (constructorInfo == null) { throw new ApplicationException(string.Format("The type {0} must declare an empty constructor (the constructor may be private, internal, protected, protected internal, or public).", type)); } DynamicMethod dynamicMethod = new DynamicMethod("InstantiateObject", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, typeof(object), null, type, true); ILGenerator generator = dynamicMethod.GetILGenerator(); generator.Emit(OpCodes.Newobj, constructorInfo); generator.Emit(OpCodes.Ret); return (InstantiateObjectHandler)dynamicMethod.CreateDelegate(typeof(InstantiateObjectHandler)); }
/// <summary> /// 动态函数 /// </summary> /// <param name="type"></param> public GetterDynamicMethod(Type type) { dynamicMethod = new DynamicMethod("formGetter", null, new Type[] { type, typeof(NameValueCollection) }, type, true); generator = dynamicMethod.GetILGenerator(); isValueType = type.IsValueType; }
private static Delegate CreateDefaultFunction <T>() { #region 初始时间 var pd = PocoData.ForType(typeof(T)); List <PropertyInfo> datetimes = new List <PropertyInfo>(); List <PropertyInfo> datetimeoffsets = new List <PropertyInfo>(); List <PropertyInfo> strings = new List <PropertyInfo>(); List <PropertyInfo> ansiStrings = new List <PropertyInfo>(); List <PropertyInfo> guids = new List <PropertyInfo>(); foreach (var item in pd.Columns) { if (item.Value.ResultColumn) { continue; } var pi = item.Value.PropertyInfo; if (pi.PropertyType == typeof(DateTime)) { datetimes.Add(pi); } else if (pi.PropertyType == typeof(DateTimeOffset)) { datetimeoffsets.Add(pi); } else if (pi.PropertyType == typeof(string)) { strings.Add(pi); } else if (pi.PropertyType == typeof(Guid)) { guids.Add(pi); } else if (pi.PropertyType == typeof(AnsiString)) { ansiStrings.Add(pi); } } #endregion #region dateTimeType dateTimeOffsetType AnsiString var dateTimeType = typeof(DateTime); //var getYear = dateTimeType.GetProperty("Year"); var getNow = dateTimeType.GetProperty("Now", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var getMinValue = dateTimeType.GetField("MinValue", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var getop_Equality = dateTimeType.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var dateTimeOffsetType = typeof(DateTimeOffset); var getNow2 = dateTimeOffsetType.GetProperty("Now", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var getMinValue2 = dateTimeOffsetType.GetField("MinValue", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var getop_Equality2 = dateTimeOffsetType.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var guidType = typeof(Guid); var getEmpty = guidType.GetField("Empty", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var getNewGuid = guidType.GetMethod("NewGuid", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var getop_Equality3 = guidType.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic); var asctor = typeof(AnsiString).GetConstructor(new Type[] { typeof(string) }); #endregion var m = new DynamicMethod("toolgood_default_" + Guid.NewGuid().ToString().Replace("-", ""), typeof(void), new Type[] { typeof(T), typeof(bool), typeof(bool), typeof(bool) }, true); var il = m.GetILGenerator(); #region string if (strings.Count > 0) { il.Emit(OpCodes.Ldarg_1); var lab1 = il.DefineLabel(); if (strings.Count < 7) { il.Emit(OpCodes.Brfalse_S, lab1); } else { il.Emit(OpCodes.Brfalse, lab1); } for (int i = 0; i < strings.Count; i++) { var item = strings[i]; il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, item.GetGetMethod()); var lab = il.DefineLabel(); il.Emit(OpCodes.Brtrue_S, lab); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Callvirt, item.GetSetMethod()); il.MarkLabel(lab); } il.MarkLabel(lab1); } #endregion #region AnsiString if (ansiStrings.Count > 0) { il.Emit(OpCodes.Ldarg_1); var lab1 = il.DefineLabel(); if (ansiStrings.Count < 7) { il.Emit(OpCodes.Brfalse_S, lab1); } else { il.Emit(OpCodes.Brfalse, lab1); } for (int i = 0; i < ansiStrings.Count; i++) { var item = ansiStrings[i]; var lab = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, item.GetGetMethod()); il.Emit(OpCodes.Brtrue_S, lab); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Newobj, asctor); il.Emit(OpCodes.Callvirt, item.GetSetMethod()); il.MarkLabel(lab); } il.MarkLabel(lab1); } #endregion #region date if (datetimes.Count + datetimeoffsets.Count > 0) { il.Emit(OpCodes.Ldarg_2); var lab2 = il.DefineLabel(); if (datetimes.Count + datetimeoffsets.Count < 5) { il.Emit(OpCodes.Brfalse_S, lab2); } else { il.Emit(OpCodes.Brfalse, lab2); } #region datetimes foreach (var item in datetimes) { var lab = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, item.GetGetMethod()); il.Emit(OpCodes.Ldsfld, getMinValue); il.Emit(OpCodes.Call, getop_Equality); il.Emit(OpCodes.Brfalse_S, lab); il.Emit(OpCodes.Ldarg_0); //il.Emit(OpCodes.Ldsfld, getMinValue); il.Emit(OpCodes.Call, getNow.GetGetMethod()); il.Emit(OpCodes.Callvirt, item.GetSetMethod()); il.MarkLabel(lab); } #endregion #region datetimeoffsets foreach (var item in datetimeoffsets) { var lab = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, item.GetGetMethod()); il.Emit(OpCodes.Ldsfld, getMinValue2); il.Emit(OpCodes.Call, getop_Equality2); il.Emit(OpCodes.Brfalse_S, lab); il.Emit(OpCodes.Ldarg_0); //il.Emit(OpCodes.Ldsfld, getMinValue); il.Emit(OpCodes.Call, getNow2.GetGetMethod()); il.Emit(OpCodes.Callvirt, item.GetSetMethod()); il.MarkLabel(lab); } #endregion il.MarkLabel(lab2); } #endregion #region guid if (guids.Count > 0) { il.Emit(OpCodes.Ldarg_3); var lab3 = il.DefineLabel(); if (guids.Count < 5) { il.Emit(OpCodes.Brfalse_S, lab3); } else { il.Emit(OpCodes.Brfalse, lab3); } foreach (var item in guids) { var lab = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, item.GetGetMethod()); il.Emit(OpCodes.Ldsfld, getEmpty); il.Emit(OpCodes.Call, getop_Equality3); il.Emit(OpCodes.Brfalse_S, lab); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, getNewGuid); il.Emit(OpCodes.Callvirt, item.GetSetMethod()); il.MarkLabel(lab); } il.MarkLabel(lab3); } #endregion il.Emit(OpCodes.Ret); return(m.CreateDelegate(Expression.GetActionType(typeof(T), typeof(bool), typeof(bool), typeof(bool)))); }
public Func <IDataRecord, T> CreateMapper <T>(IResultMapperCreateContext context, MethodInfo mi, ColumnInfo[] columns) { var type = typeof(T); var types = type.GetGenericArguments(); var selector = (IMultiMappingSelector)context.ServiceProvider.GetService(typeof(IMultiMappingSelector)); var typeMaps = selector.Select(mi, types, columns); var converters = typeMaps.SelectMany(typeMap => typeMap.Constructor.Parameters .Select(x => new { x.Index, Converter = context.GetConverter(columns[x.Index].Type, x.Info.ParameterType, x.Info) }) .Concat(typeMap.Properties .Select(x => new { x.Index, Converter = context.GetConverter(columns[x.Index].Type, x.Info.PropertyType, x.Info) }))) .Where(x => x.Converter != null) .ToDictionary(x => x.Index, x => x.Converter); var holder = CreateHolder(converters); var holderType = holder.GetType(); var dynamicMethod = new DynamicMethod(string.Empty, type, new[] { holderType, typeof(IDataRecord) }, true); var ilGenerator = dynamicMethod.GetILGenerator(); // Variables var objectLocal = converters.Count > 0 ? ilGenerator.DeclareLocal(typeof(object)) : null; var valueTypeLocals = ilGenerator.DeclareValueTypeLocals( typeMaps.SelectMany(typeMap => typeMap.Constructor.Parameters.Select(x => x.Info.ParameterType) .Concat(typeMap.Properties.Select(x => x.Info.PropertyType)))); var isShort = valueTypeLocals.Count + (objectLocal != null ? 1 : 0) <= 256; foreach (var typeMap in typeMaps) { // -------------------------------------------------------------------------------- // Constructor // -------------------------------------------------------------------------------- foreach (var parameterMap in typeMap.Constructor.Parameters) { var hasValueLabel = ilGenerator.DefineLabel(); var next = ilGenerator.DefineLabel(); // Stack ilGenerator.EmitStackColumnValue(parameterMap.Index); ilGenerator.EmitCheckDbNull(); ilGenerator.Emit(OpCodes.Brfalse_S, hasValueLabel); // Null ilGenerator.Emit(OpCodes.Pop); ilGenerator.EmitStackDefault(parameterMap.Info.ParameterType, valueTypeLocals, isShort); ilGenerator.Emit(OpCodes.Br_S, next); // Value ilGenerator.MarkLabel(hasValueLabel); if (converters.ContainsKey(parameterMap.Index)) { ilGenerator.EmitConvertByField(holderType.GetField($"parser{parameterMap.Index}"), objectLocal, isShort); } ilGenerator.EmitTypeConversion(parameterMap.Info.ParameterType); // Next ilGenerator.MarkLabel(next); } // New ilGenerator.Emit(OpCodes.Newobj, typeMap.Constructor.Info); // -------------------------------------------------------------------------------- // Property // -------------------------------------------------------------------------------- foreach (var propertyMap in typeMap.Properties) { var hasValueLabel = ilGenerator.DefineLabel(); var next = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Dup); // Stack ilGenerator.EmitStackColumnValue(propertyMap.Index); ilGenerator.EmitCheckDbNull(); ilGenerator.Emit(OpCodes.Brfalse_S, hasValueLabel); // Null ilGenerator.Emit(OpCodes.Pop); ilGenerator.EmitStackDefault(propertyMap.Info.PropertyType, valueTypeLocals, isShort); ilGenerator.Emit(OpCodes.Br_S, next); // Value ilGenerator.MarkLabel(hasValueLabel); if (converters.ContainsKey(propertyMap.Index)) { ilGenerator.EmitConvertByField(holderType.GetField($"parser{propertyMap.Index}"), objectLocal, isShort); } ilGenerator.EmitTypeConversion(propertyMap.Info.PropertyType); // Next ilGenerator.MarkLabel(next); // Set ilGenerator.Emit(type.IsValueType ? OpCodes.Call : OpCodes.Callvirt, propertyMap.Info.SetMethod); } } ilGenerator.Emit(OpCodes.Newobj, type.GetConstructor(types)); ilGenerator.Emit(OpCodes.Ret); return((Func <IDataRecord, T>)dynamicMethod.CreateDelegate(typeof(Func <IDataRecord, T>), holder)); }
public CompiledMethods(Type type) { { var dm = new DynamicMethod("serialize1", typeof(byte[]), new[] { typeof(object), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); // obj il.EmitUnboxOrCast(type); il.EmitLdarg(1); il.EmitCall(GetMethod(type, "Serialize", new[] { null, typeof(IJsonFormatterResolver) })); il.Emit(OpCodes.Ret); serialize1 = CreateDelegate <Func <object, IJsonFormatterResolver, byte[]> >(dm); } { var dm = new DynamicMethod("serialize2", null, new[] { typeof(Stream), typeof(object), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); // stream il.EmitLdarg(1); il.EmitUnboxOrCast(type); il.EmitLdarg(2); il.EmitCall(GetMethod(type, "Serialize", new[] { typeof(Stream), null, typeof(IJsonFormatterResolver) })); il.Emit(OpCodes.Ret); serialize2 = CreateDelegate <Action <Stream, object, IJsonFormatterResolver> >(dm); } { var dm = new DynamicMethod("serialize3", null, new[] { typeof(JsonWriter).MakeByRefType(), typeof(object), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); // ref writer il.EmitLdarg(1); il.EmitUnboxOrCast(type); il.EmitLdarg(2); il.EmitCall(GetMethod(type, "Serialize", new[] { typeof(JsonWriter).MakeByRefType(), null, typeof(IJsonFormatterResolver) })); il.Emit(OpCodes.Ret); serialize3 = CreateDelegate <SerializeJsonWriter>(dm); } { var dm = new DynamicMethod("serializeUnsafe", typeof(ArraySegment <byte>), new[] { typeof(object), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); // obj il.EmitUnboxOrCast(type); il.EmitLdarg(1); il.EmitCall(GetMethod(type, "SerializeUnsafe", new[] { null, typeof(IJsonFormatterResolver) })); il.Emit(OpCodes.Ret); serializeUnsafe = CreateDelegate <Func <object, IJsonFormatterResolver, ArraySegment <byte> > >(dm); } { var dm = new DynamicMethod("toJsonString", typeof(string), new[] { typeof(object), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); // obj il.EmitUnboxOrCast(type); il.EmitLdarg(1); il.EmitCall(GetMethod(type, "ToJsonString", new[] { null, typeof(IJsonFormatterResolver) })); il.Emit(OpCodes.Ret); toJsonString = CreateDelegate <Func <object, IJsonFormatterResolver, string> >(dm); } { var dm = new DynamicMethod("Deserialize", typeof(object), new[] { typeof(string), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); il.EmitLdarg(1); il.EmitCall(GetMethod(type, "Deserialize", new[] { typeof(string), typeof(IJsonFormatterResolver) })); il.EmitBoxOrDoNothing(type); il.Emit(OpCodes.Ret); deserialize1 = CreateDelegate <Func <string, IJsonFormatterResolver, object> >(dm); } { var dm = new DynamicMethod("Deserialize", typeof(object), new[] { typeof(byte[]), typeof(int), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); il.EmitLdarg(1); il.EmitLdarg(2); il.EmitCall(GetMethod(type, "Deserialize", new[] { typeof(byte[]), typeof(int), typeof(IJsonFormatterResolver) })); il.EmitBoxOrDoNothing(type); il.Emit(OpCodes.Ret); deserialize2 = CreateDelegate <Func <byte[], int, IJsonFormatterResolver, object> >(dm); } { var dm = new DynamicMethod("Deserialize", typeof(object), new[] { typeof(Stream), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); il.EmitLdarg(1); il.EmitCall(GetMethod(type, "Deserialize", new[] { typeof(Stream), typeof(IJsonFormatterResolver) })); il.EmitBoxOrDoNothing(type); il.Emit(OpCodes.Ret); deserialize3 = CreateDelegate <Func <Stream, IJsonFormatterResolver, object> >(dm); } { var dm = new DynamicMethod("Deserialize", typeof(object), new[] { typeof(JsonReader).MakeByRefType(), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); // ref reader il.EmitLdarg(1); il.EmitCall(GetMethod(type, "Deserialize", new[] { typeof(JsonReader).MakeByRefType(), typeof(IJsonFormatterResolver) })); il.EmitBoxOrDoNothing(type); il.Emit(OpCodes.Ret); deserialize4 = CreateDelegate <DeserializeJsonReader>(dm); } #if NETSTANDARD { var dm = new DynamicMethod("SerializeAsync", typeof(System.Threading.Tasks.Task), new[] { typeof(Stream), typeof(object), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); // stream il.EmitLdarg(1); il.EmitUnboxOrCast(type); il.EmitLdarg(2); il.EmitCall(GetMethod(type, "SerializeAsync", new[] { typeof(Stream), null, typeof(IJsonFormatterResolver) })); il.Emit(OpCodes.Ret); serializeAsync = CreateDelegate <Func <Stream, object, IJsonFormatterResolver, System.Threading.Tasks.Task> >(dm); } { var dm = new DynamicMethod("DeserializeAsync", typeof(System.Threading.Tasks.Task <object>), new[] { typeof(Stream), typeof(IJsonFormatterResolver) }, type.Module, true); var il = dm.GetILGenerator(); il.EmitLdarg(0); il.EmitLdarg(1); il.EmitCall(GetMethod(type, "DeserializeAsync", new[] { typeof(Stream), typeof(IJsonFormatterResolver) })); il.EmitCall(typeof(CompiledMethods).GetMethod("TaskCast", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(type)); il.Emit(OpCodes.Ret); deserializeAsync = CreateDelegate <Func <Stream, IJsonFormatterResolver, System.Threading.Tasks.Task <object> > >(dm); } #endif }
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.IsValueType) { il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Unbox, parameterType); } else { il.Emit(OpCodes.Ldelema, parameterType); } } else { il.Emit(OpCodes.Ldelem_Ref); if (parameterType.IsValueType) { il.Emit(OpCodes.Unbox, parameterType); il.Emit(OpCodes.Ldobj, parameterType); } } } if ((method.IsAbstract || method.IsVirtual) && !method.IsFinal && !method.DeclaringType.IsSealed) { il.Emit(OpCodes.Callvirt, method); } else { il.Emit(OpCodes.Call, method); } if (method.ReturnType == typeof(void)) { il.Emit(OpCodes.Ldnull); } else if (method.ReturnType.IsValueType) { il.Emit(OpCodes.Box, method.ReturnType); } il.Emit(OpCodes.Ret); return((MethodDelegate)dm.CreateDelegate(typeof(MethodDelegate))); }
private static IDispatchInvokeDelegate Create_IDispatchInvoke(bool returnResult) { const int dispatchPointerIndex = 0; const int memberDispIdIndex = 1; const int flagsIndex = 2; const int dispParamsIndex = 3; const int resultIndex = 4; const int exceptInfoIndex = 5; const int argErrIndex = 6; Debug.Assert(argErrIndex + 1 == typeof(IDispatchInvokeDelegate).GetMethod("Invoke").GetParameters().Length); Type[] paramTypes = new Type[argErrIndex + 1]; paramTypes[dispatchPointerIndex] = typeof(IntPtr); paramTypes[memberDispIdIndex] = typeof(int); paramTypes[flagsIndex] = typeof(ComTypes.INVOKEKIND); paramTypes[dispParamsIndex] = typeof(ComTypes.DISPPARAMS).MakeByRefType(); paramTypes[resultIndex] = typeof(Variant).MakeByRefType(); paramTypes[exceptInfoIndex] = typeof(ExcepInfo).MakeByRefType(); paramTypes[argErrIndex] = typeof(uint).MakeByRefType(); // Define the dynamic method in our assembly so we skip verification DynamicMethod dm = new DynamicMethod("IDispatchInvoke", typeof(int), paramTypes, DynamicModule); ILGenerator method = dm.GetILGenerator(); // return functionPtr(...) EmitLoadArg(method, dispatchPointerIndex); EmitLoadArg(method, memberDispIdIndex); // burn the address of our empty IID in directly. This is never freed, relocated, etc... // Note passing this as a Guid directly results in a ~30% perf hit for IDispatch invokes so // we also pass it directly as an IntPtr instead. if (IntPtr.Size == 4) { method.Emit(OpCodes.Ldc_I4, UnsafeMethods.NullInterfaceId.ToInt32()); // riid } else { method.Emit(OpCodes.Ldc_I8, UnsafeMethods.NullInterfaceId.ToInt64()); // riid } method.Emit(OpCodes.Conv_I); method.Emit(OpCodes.Ldc_I4_0); // lcid EmitLoadArg(method, flagsIndex); EmitLoadArg(method, dispParamsIndex); if (returnResult) { EmitLoadArg(method, resultIndex); } else { method.Emit(OpCodes.Ldsfld, typeof(IntPtr).GetField("Zero")); } EmitLoadArg(method, exceptInfoIndex); EmitLoadArg(method, argErrIndex); // functionPtr = *(IntPtr*)(*(dispatchPointer) + VTABLE_OFFSET) int idispatchInvokeOffset = ((int)IDispatchMethodIndices.IDispatch_Invoke) * Marshal.SizeOf(typeof(IntPtr)); EmitLoadArg(method, dispatchPointerIndex); method.Emit(OpCodes.Ldind_I); method.Emit(OpCodes.Ldc_I4, idispatchInvokeOffset); method.Emit(OpCodes.Add); method.Emit(OpCodes.Ldind_I); SignatureHelper signature = SignatureHelper.GetMethodSigHelper(CallingConvention.Winapi, typeof(int)); Type[] invokeParamTypes = new Type[] { typeof(IntPtr), // dispatchPointer typeof(int), // memberDispId typeof(IntPtr), // riid typeof(int), // lcid typeof(ushort), // flags typeof(IntPtr), // dispParams typeof(IntPtr), // result typeof(IntPtr), // excepInfo typeof(IntPtr), // argErr }; signature.AddArguments(invokeParamTypes, null, null); method.Emit(OpCodes.Calli, signature); method.Emit(OpCodes.Ret); return((IDispatchInvokeDelegate)dm.CreateDelegate(typeof(IDispatchInvokeDelegate))); }
/// <summary> /// Return delegate through which can be call in place constructor on already created object. /// </summary> /// <remarks> /// Call it like var ctorInPlace = (Action<T, P1, P2 ...>)ConstructorHelper<T>.CreateInPlaceConstructor(typeof(Action<T, P1, P2 ...>); /// ctorInPlace(obj, param1, param2 ...) /// </remarks> /// <param name="constructorType">Type of Action representing constructor, where fist parameter is hidden this value.</remarks></param> /// <returns></returns> public static Delegate CreateInPlaceConstructor(Type constructorType) { var type = typeof(T); var inplaceCtorMethod = constructorType.GetMethod("Invoke"); var inplaceCtorParams = Array.ConvertAll(inplaceCtorMethod.GetParameters(), p => p.ParameterType); Type[] ctorParams; if (inplaceCtorParams.Length > 1) { ctorParams = new Type[inplaceCtorParams.Length - 1]; Array.ConstrainedCopy(inplaceCtorParams, 1, ctorParams, 0, inplaceCtorParams.Length - 1); } else { ctorParams = Type.EmptyTypes; } ConstructorInfo constructor = type.GetConstructor(ctorParams); if (constructor == null) { throw new InvalidOperationException(string.Format("No matching constructor for object {0} was found!", type.Name)); } var dm = new DynamicMethod(string.Format("Pool<T>__{0}", Guid.NewGuid().ToString().Replace("-", "")), typeof(void), inplaceCtorParams, typeof(ConstructorHelper <T>), false); var gen = dm.GetILGenerator(); for (int paramIdx = 0; paramIdx < inplaceCtorParams.Length; paramIdx++) { if (paramIdx < 4) { switch (paramIdx) { 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, paramIdx); } } gen.Emit(OpCodes.Callvirt, constructor); gen.Emit(OpCodes.Ret); return(dm.CreateDelegate(constructorType)); }
protected virtual ReadDataInvoker CreateReadDataMethod(Type type, AMFReader reader, object instance) { #if !(MONO) && !(NET_2_0) && !(NET_3_5) && !(SILVERLIGHT) bool canSkipChecks = _ps.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet); #else bool canSkipChecks = SecurityManager.IsGranted(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)); #endif DynamicMethod method = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(AMFReader), typeof(ClassDefinition) }, this.GetType(), canSkipChecks); ILGenerator il = method.GetILGenerator(); LocalBuilder instanceLocal = il.DeclareLocal(type); //[0] instance LocalBuilder typeCodeLocal = il.DeclareLocal(typeof(byte)); //[1] uint8 typeCode LocalBuilder keyLocal = il.DeclareLocal(typeof(string)); //[2] string key LocalBuilder objTmp = il.DeclareLocal(typeof(object)); //[3] temp object store LocalBuilder intTmp1 = il.DeclareLocal(typeof(int)); //[4] temp int store, length LocalBuilder intTmp2 = il.DeclareLocal(typeof(int)); //[5] temp int store, index LocalBuilder objTmp2 = il.DeclareLocal(typeof(object)); //[6] temp object store LocalBuilder typeTmp = il.DeclareLocal(typeof(Type)); //[7] temp Type store EmitHelper emit = new EmitHelper(il); ConstructorInfo typeConstructor = type.GetConstructor(EmitHelper.AnyVisibilityInstance, null, CallingConventions.HasThis, System.Type.EmptyTypes, null); MethodInfo miAddReference = typeof(AMFReader).GetMethod("AddAMF3ObjectReference"); MethodInfo miReadByte = typeof(AMFReader).GetMethod("ReadByte"); emit //object instance = new object(); .newobj(typeConstructor) //Create the new instance and push the object reference onto the evaluation stack .stloc_0 //Pop from the top of the evaluation stack and store it in a the local variable list at index 0 //reader.AddReference(instance); .ldarg_0 //Push the argument indexed at 1 onto the evaluation stack 'reader' .ldloc_0 //Loads the local variable at index 0 onto the evaluation stack 'instance' .callvirt(miAddReference) //Arguments are popped from the stack, the method call is performed, return value is pushed onto the stack //typeCode = 0; .ldc_i4_0 //Push the integer value of 0 onto the evaluation stack as an int32 .stloc_1 //Pop and store it in a the local variable list at index 1 //string key = null; .ldnull //Push a null reference onto the evaluation stack .stloc_2 //Pop and store it in a the local variable list at index 2 'key' .end() ; for (int i = 0; i < _classDefinition.MemberCount; i++) { string key = _classDefinition.Members[i].Name; byte typeCode = reader.ReadByte(); object value = reader.ReadAMF3Data(typeCode); reader.SetMember(instance, key, value); emit //.ldarg_1 //.callvirt(typeof(ClassDefinition).GetMethod("get_Members")) //.ldc_i4(i) //.conv_ovf_i //.ldelem_ref //.stloc_2 .ldarg_0 .callvirt(miReadByte) .stloc_1 .end() ; MemberInfo[] memberInfos = type.GetMember(key); if (memberInfos != null && memberInfos.Length > 0) { GeneratePropertySet(emit, typeCode, memberInfos[0]); } else { //Log this error (do not throw exception), otherwise our current AMF stream becomes unreliable log.Warn(__Res.GetString(__Res.Optimizer_Warning)); string msg = __Res.GetString(__Res.Reflection_MemberNotFound, string.Format("{0}.{1}", type.FullName, key)); log.Warn(msg); //reader.ReadAMF3Data(typeCode); emit .ldarg_0 //Push 'reader' .ldloc_1 //Push 'typeCode' .callvirt(typeof(AMFReader).GetMethod("ReadAMF3Data", new Type[] { typeof(byte) })) .pop .end() ; } } Label labelExit = emit.DefineLabel(); emit .MarkLabel(labelExit) //return instance; .ldloc_0 //Load the local variable at index 0 onto the evaluation stack .ret() //Return ; return((ReadDataInvoker)method.CreateDelegate(typeof(ReadDataInvoker))); }
public QuickSerializer( Type recordType, DbfVersion version, List <ColumnDefinition> columns, int recordWidth, bool ignoreMissingFields, bool setOffset) { mVersion = version; if (columns == null) { columns = new List <ColumnDefinition>(); mCreateColumns = true; } mColumns = columns; mIgnoreMissingFields = ignoreMissingFields; mRecordWidth = 0; // dbf use a character to specify deleted record mIsFixedRecordWidth = true; var readMethod = new DynamicMethod("__readRecord", null, new Type[] { typeof(IHasEncoding), typeof(Byte[]), typeof(object) }, recordType, true); mIlRead = readMethod.GetILGenerator(); var writeMethod = new DynamicMethod("__writeRecord", null, new Type[] { typeof(IHasEncoding), typeof(Byte[]), typeof(object) }, recordType, true); mIlWrite = writeMethod.GetILGenerator(); var compareMethod = new DynamicMethod("__compareRecord", typeof(int), new Type[] { typeof(IHasEncoding), typeof(object), typeof(object) }, recordType, true); mIlCompare = compareMethod.GetILGenerator(); EnumerateFields(recordType); int currentOffset = 0; int columnIndex = 0; foreach (var cd in mColumns) { if (setOffset) { cd.mOffset = currentOffset; currentOffset += cd.mWidth; } cd.ColumnIndex = columnIndex++; EmitColumnCode(cd); } mRecordWidth = currentOffset; mIlRead.Emit(OpCodes.Ret); mIlWrite.Emit(OpCodes.Ret); mIlCompare.Emit(OpCodes.Ldc_I4_0); // if not return yet, we can say that the records are equal mIlCompare.Emit(OpCodes.Ret); mQuickReadMethod = (QuickReadDelegate)readMethod.CreateDelegate(typeof(QuickReadDelegate)); mQuickWriteMethod = (QuickWriteDelegate)writeMethod.CreateDelegate(typeof(QuickWriteDelegate)); mQuickCompareMethod = (QuickCompareDelegate)compareMethod.CreateDelegate(typeof(QuickCompareDelegate)); if (recordWidth > 0) { mRecordWidth = recordWidth; } }
protected virtual Func <object, object[], object> CreateInvoker() { DynamicMethod dynamicMethod = new DynamicMethod($"invoker_{_displayName}", typeof(object), new Type[] { typeof(object), typeof(object[]) }, _reflectionInfo.Module, true); ILGenerator ilGen = dynamicMethod.GetILGenerator(); var parameterTypes = _reflectionInfo.GetParameterTypes(); ilGen.EmitLoadArg(0); ilGen.EmitConvertFromObject(_reflectionInfo.DeclaringType); if (parameterTypes.Length == 0) { return(CreateDelegate()); } var refParameterCount = parameterTypes.Count(x => x.IsByRef); if (refParameterCount == 0) { for (var i = 0; i < parameterTypes.Length; i++) { ilGen.EmitLoadArg(1); ilGen.EmitInt(i); ilGen.Emit(OpCodes.Ldelem_Ref); ilGen.EmitConvertFromObject(parameterTypes[i]); } return(CreateDelegate()); } var indexedLocals = new IndexedLocalBuilder[refParameterCount]; var index = 0; for (var i = 0; i < parameterTypes.Length; i++) { ilGen.EmitLoadArg(1); ilGen.EmitInt(i); ilGen.Emit(OpCodes.Ldelem_Ref); if (parameterTypes[i].IsByRef) { var defType = parameterTypes[i].GetElementType(); var indexedLocal = new IndexedLocalBuilder(ilGen.DeclareLocal(defType), i); indexedLocals[index++] = indexedLocal; ilGen.EmitConvertFromObject(defType); ilGen.Emit(OpCodes.Stloc, indexedLocal.LocalBuilder); ilGen.Emit(OpCodes.Ldloca, indexedLocal.LocalBuilder); } else { ilGen.EmitConvertFromObject(parameterTypes[i]); } } return(CreateDelegate(() => { for (var i = 0; i < indexedLocals.Length; i++) { ilGen.EmitLoadArg(1); ilGen.EmitInt(indexedLocals[i].Index); ilGen.Emit(OpCodes.Ldloc, indexedLocals[i].LocalBuilder); ilGen.EmitConvertToObject(indexedLocals[i].LocalType); ilGen.Emit(OpCodes.Stelem_Ref); } })); Func <object, object[], object> CreateDelegate(Action callback = null) { ilGen.EmitCall(OpCodes.Callvirt, _reflectionInfo, null); callback?.Invoke(); if (_reflectionInfo.ReturnType == typeof(void)) { ilGen.Emit(OpCodes.Ldnull); } else if (_reflectionInfo.ReturnType.IsValueType) { ilGen.EmitConvertToObject(_reflectionInfo.ReturnType); } ilGen.Emit(OpCodes.Ret); return((Func <object, object[], object>)dynamicMethod.CreateDelegate(typeof(Func <object, object[], object>))); } }
public DynamicScopeTokenResolver(DynamicMethod dm) { m_scope = s_scopeFi.GetValue(dm.GetILGenerator()); }
/// <summary> /// 数据实体 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dt"></param> /// <returns></returns> public static List <T> DataTableToList <T>(DataTable dt) { List <T> list = new List <T>(); if (dt == null) { return(list); } //声明 委托Load<T>的一个实例rowMap Load <T> rowMap = null; Delegate key = null; //从rowMapMethods查找当前T类对应的转换方法,没有则使用Emit构造一个。 //if (!rowMapMethods.ContainsKey(typeof(T))) if (!rowMapMethods.TryGetValue(typeof(T), out key)) { DynamicMethod method = new DynamicMethod("DynamicCreateEntity_" + typeof(T).Name, typeof(T), new Type[] { typeof(DataRow) }, typeof(T), true); ILGenerator generator = method.GetILGenerator(); LocalBuilder result = generator.DeclareLocal(typeof(T)); generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for (int index = 0; index < dt.Columns.Count; index++) { //StringComparison.CurrentCultureIgnoreCase PropertyInfo propertyInfo = typeof(T).GetProperty(dt.Columns[index].ColumnName); Label endIfLabel = generator.DefineLabel(); if (propertyInfo != null && propertyInfo.GetSetMethod() != null) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, index); 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, index); generator.Emit(OpCodes.Callvirt, getValueMethod); generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); generator.MarkLabel(endIfLabel); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); //构造完成以后传给rowMap rowMap = (Load <T>)method.CreateDelegate(typeof(Load <T>)); } else { rowMap = (Load <T>)rowMapMethods[typeof(T)]; } //遍历Datatable的rows集合,调用rowMap把DataRow转换为对象(T) foreach (DataRow info in dt.Rows) { list.Add(rowMap(info)); } return(list); }
/// <summary> /// Creates a Delegate wrapper that allows a parameterless method to be used as /// an event handler for an event that defines parameters. This enables the use /// of "notification" event handlers - Methods which either cannot make use of /// or don't care about event parameters. /// </summary> private Delegate createDynamicWrapper( object target, Type delegateType, ParameterInfo[] eventParams, MethodInfo eventHandler ) { #if UNITY_IPHONE throw new InvalidOperationException( "Dynamic code generation is not supported on iOS devices" ); #else var paramTypes = new Type[] { target.GetType() } .Concat( eventParams.Select( p => p.ParameterType ) ) .ToArray(); var handler = new DynamicMethod( "DynamicEventWrapper_" + eventHandler.Name, typeof( void ), paramTypes ); var il = handler.GetILGenerator(); il.Emit( OpCodes.Ldarg_0 ); il.EmitCall( OpCodes.Callvirt, eventHandler, Type.EmptyTypes ); il.Emit( OpCodes.Ret ); return handler.CreateDelegate( delegateType, target ); #endif }
internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyInfo, bool ShowReadOnlyProperties) { MethodInfo 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); } Type[] arguments = new Type[2]; arguments[0] = arguments[1] = typeof(object); DynamicMethod setter = new DynamicMethod("_csm", typeof(object), arguments, true);// !setMethod.IsPublic); // fix: skipverify ILGenerator 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> /// 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.Concat(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().ToString(), 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 var targetMemberType = lastMemberAccess?.Type; int sizeToSet = (!size.HasValue && targetMemberType == typeof(string)) ? DbString.DefaultLength : size ?? 0; if (parameters.TryGetValue(dynamicParamName, out ParamInfo parameter)) { parameter.ParameterDirection = parameter.AttachedParam.Direction = ParameterDirection.InputOutput; if (parameter.AttachedParam.Size == 0) { parameter.Size = parameter.AttachedParam.Size = sizeToSet; } } else { dbType = (!dbType.HasValue) #pragma warning disable 618 ? SqlMapper.LookupDbType(targetMemberType, targetMemberType?.Name, true, out SqlMapper.ITypeHandler 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); }