示例#1
0
        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}"));
        }
示例#4
0
        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);
    }
示例#7
0
文件: test2.cs 项目: mono/gert
	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");
	}
示例#8
0
文件: test.cs 项目: mono/gert
	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);
	}
示例#9
0
文件: test.cs 项目: mono/gert
	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);
        }
示例#11
0
文件: test.cs 项目: mono/gert
	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]);
	}
示例#12
0
文件: task5.cs 项目: seniorivn/ITMO
 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);
        }
示例#14
0
	public static int Main()
	{

		DynamicMethod method_builder = new DynamicMethod ("WriteHello" , typeof (int), new Type[] {typeof (Driver)}, typeof (Driver));
		ILGenerator ilg = method_builder.GetILGenerator ();

		ilg.Emit (OpCodes.Ldarg_0);
		ilg.Emit (OpCodes.Call, typeof (Driver).GetMethod ("Foo"));
		ilg.Emit (OpCodes.Ret);

		int res = (int) method_builder.Invoke (null, new object[] {new Driver()});
		return res == -99 ? 0 : 1;
	}
        public void ILGenerator_Int_Type(bool skipVisibility)
        {
            IDClass target = new IDClass();
            FieldInfo field = typeof(IDClass).GetField(FieldName, BindingFlags.Instance | BindingFlags.NonPublic);

            Type[] paramTypes = new Type[] { typeof(IDClass), typeof(int) };
            DynamicMethod method = new DynamicMethod("Method", typeof(int), paramTypes, typeof(IDClass), skipVisibility);
            
            ILGenerator ilGenerator = method.GetILGenerator(8);
            Helpers.EmitMethodBody(ilGenerator, field);

            IntDelegate instanceCallBack = (IntDelegate)method.CreateDelegate(typeof(IntDelegate), target);
            VerifyILGenerator(instanceCallBack, target, 0);
        }
 public static int Main()
 {
     DynamicMethod
     method_builder
     =
     new
     DynamicMethod
     ("ThrowException"
     ,
     typeof
     (void),
     new
     Type[0],
     typeof
     (Driver));
     ILGenerator
     ilg
     =
     method_builder.GetILGenerator
     ();
     ilg.Emit
     (OpCodes.Newobj,
     typeof
     (MyException).GetConstructor
     (new
     Type[0]));
     ilg.Emit
     (OpCodes.Throw);
     try
     {
     method_builder.Invoke
     (null,
     null);
     return
     2;
     }
     catch
     (TargetInvocationException
     tie)
     {
     if(!
     (tie.InnerException
     is
     MyException))
     return
     3;
     }
     return
     0;
 }
    static 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);
    }
示例#18
0
文件: test1.cs 项目: mono/gert
	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);
        }
示例#20
0
    static DynamicMethod EmitDynamicMethod(MethodInfo callee)
    {
        DynamicMethod method = new DynamicMethod(
            "MyMethod", 
            typeof(void), 
            new Type[0], 
            typeof(My).GetTypeInfo().Module);

        ILGenerator il = method.GetILGenerator();
        for (int i = 0; i < 5; i++)
            il.Emit(OpCodes.Call, callee);
        il.Emit(OpCodes.Ret);

        return method;
    }
示例#21
0
    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");
    }
示例#22
0
        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));
        }
示例#23
0
        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;
        }
示例#24
0
文件: test.cs 项目: mono/gert
	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));
        }
示例#26
0
        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);
                }
            }
        }
示例#28
0
        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);
        }
示例#29
0
        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>));
            }
        }
示例#30
0
 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));
 }
示例#31
0
        /// <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));
        }
示例#32
0
	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;
	}
示例#33
0
        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);
        }
示例#34
0
 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);
 }
示例#35
0
文件: IL.cs 项目: hpc-dal/HPC.DAL
        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));
        }
示例#36
0
        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)));
        }
示例#37
0
        // 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));
            }
                                     ));
        }
示例#38
0
        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));
        }
示例#39
0
        /// <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));
        }
示例#40
0
            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"));
        }
示例#42
0
文件: Program.cs 项目: sbluen/sample
    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]);
    }
示例#43
0
 /// <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));
        }
示例#45
0
 /// <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;
 }
示例#46
0
        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));
        }
示例#48
0
                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
                }
示例#49
0
        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)));
        }
示例#50
0
        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)));
        }
示例#51
0
        /// <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)));
        }
示例#53
0
        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;
            }
        }
示例#54
0
        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>)));
            }
        }
示例#55
0
 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);
        }
示例#57
0
    /// <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
    }
示例#58
0
        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);
        }