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);
	}
Пример #2
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");
	}
Пример #3
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]);
	}
Пример #4
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);
        }
Пример #5
0
 public EmitCalculator(string term, int a, int b, int c, int d)
 {
     this.dm = new DynamicMethod( "Evaluate"
                                , typeof(int)
                                , new Type[] {typeof(int),typeof(int),typeof(int),typeof(int),typeof(int)}
                                , typeof(int)
                                );
     this.tokens = term.Split(new Char[] {' '});
     this.ilGen = dm.GetILGenerator();
     this.GenCode();
     Evaluate eval = (Evaluate) dm.CreateDelegate(typeof(Evaluate));
     Console.WriteLine(eval(a, b, c, d, 0));
 }
Пример #6
0
        public void CreateDelegate_Type(IDClass target)
        {
            int newId = 0;

            FieldInfo field = typeof(IDClass).GetField(FieldName, BindingFlags.NonPublic | BindingFlags.Instance);
            DynamicMethod method = new DynamicMethod("Method", typeof(int), new Type[] { typeof(IDClass), typeof(int) }, typeof(IDClass));
            ILGenerator ilGenerator = method.GetILGenerator();
            Helpers.EmitMethodBody(ilGenerator, field);

            IDClassDelegate staticCallBack = (IDClassDelegate)method.CreateDelegate(typeof(IDClassDelegate));
            Assert.Equal(staticCallBack(target, newId), target.ID);
            Assert.Equal(newId, target.ID);
        }
        public 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);
        }
Пример #8
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;
	}
Пример #9
0
        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);
        }
Пример #10
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");
    }
Пример #11
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));
        }
Пример #12
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;
        }
Пример #13
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;
        }
Пример #14
0
        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"));
        }
Пример #15
0
            private static Action <DataRow, T> GenerateFill()
            {
                var dynamicMethod =
                    new DynamicMethod($"__Extensions__Fill__Of__{typeof(T).Name}", typeof(void),
                                      new[] { typeof(DataRow), typeof(T) }, typeof(T), true);

                var generator = dynamicMethod.GetILGenerator();

                for (var i = 0; i < PropertyInfos.Length; i++)
                {
                    generator.Emit(OpCodes.Ldarg_0);
                    switch (i)
                    {
                    case 0:
                        generator.Emit(OpCodes.Ldc_I4_0);
                        break;

                    case 1:
                        generator.Emit(OpCodes.Ldc_I4_1);
                        break;

                    case 2:
                        generator.Emit(OpCodes.Ldc_I4_2);
                        break;

                    case 3:
                        generator.Emit(OpCodes.Ldc_I4_3);
                        break;

                    case 4:
                        generator.Emit(OpCodes.Ldc_I4_4);
                        break;

                    case 5:
                        generator.Emit(OpCodes.Ldc_I4_5);
                        break;

                    case 6:
                        generator.Emit(OpCodes.Ldc_I4_6);
                        break;

                    case 7:
                        generator.Emit(OpCodes.Ldc_I4_7);
                        break;

                    case 8:
                        generator.Emit(OpCodes.Ldc_I4_8);
                        break;

                    default:
                        if (i <= 127)
                        {
                            generator.Emit(OpCodes.Ldc_I4_S, (byte)i);
                        }
                        else
                        {
                            generator.Emit(OpCodes.Ldc_I4, i);
                        }
                        break;
                    }
                    generator.Emit(OpCodes.Ldarg_1);
                    generator.Emit(OpCodes.Callvirt, PropertyInfos[i].GetGetMethod(true));
                    if (PropertyInfos[i].PropertyType.IsValueType)
                    {
                        generator.Emit(OpCodes.Box, PropertyInfos[i].PropertyType);
                    }
                    // ReSharper disable AssignNullToNotNullAttribute
                    generator.Emit(OpCodes.Callvirt, typeof(DataRow).GetMethod("set_Item", new[] { typeof(int), typeof(object) }));
                    // ReSharper restore AssignNullToNotNullAttribute
                }
                generator.Emit(OpCodes.Ret);
                return((Action <DataRow, T>)dynamicMethod.CreateDelegate(typeof(Action <DataRow, T>)));
            }
Пример #16
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
    }
Пример #17
0
        public void Precache()
        {
            Type          type   = typeof(CallModel);
            DynamicMethod method = new DynamicMethod("GetString", typeof(string), new Type[] { type });
            ILGenerator   il     = method.GetILGenerator();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, type.GetField("Age"));
            il.Emit(OpCodes.Ret);
            EmitGetString = (Func <CallModel, string>)(method.CreateDelegate(typeof(Func <CallModel, string>)));

            method = new DynamicMethod("GetDateTime", typeof(DateTime), new Type[] { type });
            il     = method.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, type.GetField("CreateTime"));
            il.Emit(OpCodes.Ret);
            EmitGetDateTime = (Func <CallModel, DateTime>)(method.CreateDelegate(typeof(Func <CallModel, DateTime>)));


            method = new DynamicMethod("SetDateString", null, new Type[] { type, typeof(string) });
            il     = method.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Stfld, type.GetField("Age"));
            il.Emit(OpCodes.Ret);
            EmitSetString = (Action <CallModel, string>)(method.CreateDelegate(typeof(Action <CallModel, string>)));

            method = new DynamicMethod("SetDateTime", null, new Type[] { type, typeof(DateTime) });
            il     = method.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Stfld, type.GetField("CreateTime"));
            il.Emit(OpCodes.Ret);
            EmitSetDateTime = (Action <CallModel, DateTime>)(method.CreateDelegate(typeof(Action <CallModel, DateTime>)));

            NatashaGetString = Natasha
                               .FastMethodOperator
                               .New
                               .Param <CallModel>("obj")
                               .MethodBody("return obj.Age;")
                               .Return <string>()
                               .Complie <Func <CallModel, string> >();

            NatashaGetDateTime = Natasha
                                 .FastMethodOperator
                                 .New
                                 .Param <CallModel>("obj")
                                 .MethodBody("return obj.CreateTime;")
                                 .Return <DateTime>()
                                 .Complie <Func <CallModel, DateTime> >();

            NatashaSetString = Natasha
                               .FastMethodOperator
                               .New
                               .Param <CallModel>("obj")
                               .Param <string>("str")
                               .MethodBody("obj.Age=str;")
                               .Return()
                               .Complie <Action <CallModel, string> >();

            NatashaSetDateTime = Natasha
                                 .FastMethodOperator
                                 .New
                                 .Param <CallModel>("obj")
                                 .Param <DateTime>("time")
                                 .MethodBody("obj.CreateTime=time;")
                                 .Return()
                                 .Complie <Action <CallModel, DateTime> >();
        }
Пример #18
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);
 }
Пример #19
0
 /// <summary>
 /// 创建 SQL 条件委托
 /// </summary>
 /// <returns>SQL 条件委托</returns>
 public Delegate Create <delegateType>()
 {
     generator.Emit(OpCodes.Ret);
     return(dynamicMethod.CreateDelegate(typeof(delegateType)));
 }
Пример #20
0
        static TaskContinuationGenerator()
        {
            DynamicMethod continuationMethod = IntegrationMapper.CreateAsyncEndMethodDelegate(typeof(TIntegration), typeof(TTarget), typeof(object));

            if (continuationMethod != null)
            {
                _continuation = (Func <TTarget, object, Exception, CallTargetState, object>)continuationMethod.CreateDelegate(typeof(Func <TTarget, object, Exception, CallTargetState, object>));
            }

            _continuationAction = new Action <Task, object>(ContinuationAction);
        }
Пример #21
0
 /// <summary>
 /// Create an advice that runs after the advised method only if it exits by throwing an exception.
 /// </summary>
 /// <param name="reflection">Reflection</param>
 /// <param name="advice">Delegate used to emit code to be invoked after the advised method</param>
 /// <returns>Advice</returns>
 static public Advice Throwing(this Advice.Style.Reflection.IAfter reflection, Action <ILGenerator> advice)
 {
     return(new Advice((_Method, _Pointer, _Boundary) =>
     {
         var _type = _Method.ReturnType();
         var _signature = _Method.Signature();
         var _method = new DynamicMethod(string.Empty, _type, _signature, _Method.Module, true);
         var _body = _method.GetILGenerator();
         if (_Boundary != null) //TODO dynamic implementation of boundary will avoid redirection overhead.
         {
             var _action = new DynamicMethod(string.Empty, Runtime.Void, new Type[] { Metadata <object> .Type, Metadata <object> .Type, Metadata <object[]> .Type, Metadata <Exception> .Type }, true);
             var _redirection = _action.GetILGenerator();
             if (_signature.Instance != null)
             {
                 _redirection.Emit(OpCodes.Ldarg_1);
                 if (_signature.Instance.IsValueType)
                 {
                     _redirection.Emit(OpCodes.Unbox_Any, _signature.Instance);
                 }
                 else
                 {
                     _redirection.Emit(OpCodes.Castclass, _signature.Instance);
                 }
             }
             for (var _index = 0; _index < _signature.Length; _index++)
             {
                 var _parameter = _signature[_index];
                 _redirection.Emit(OpCodes.Ldarg_2);
                 _redirection.Emit(OpCodes.Ldc_I4, _index); //TODO shortcut
                 _redirection.Emit(OpCodes.Ldelem_Ref);
                 if (_parameter.IsValueType)
                 {
                     _redirection.Emit(OpCodes.Unbox_Any, _parameter);
                 }
                 else
                 {
                     _redirection.Emit(OpCodes.Castclass, _parameter);
                 }
             }
             if (_type != Runtime.Void)
             {
                 var _exception = Advice.Module.DefineThreadField("<Exception>", Metadata <Exception> .Type);
                 _redirection.Emit(OpCodes.Ldarg_3);
                 _redirection.Emit(OpCodes.Stsfld, _exception);
                 _body.Emit(OpCodes.Ldsfld, _exception);
                 _body.Emit(OpCodes.Ldnull);
                 _body.Emit(OpCodes.Stsfld, _exception);
             }
             _body.Emit(advice);
             _body.Emit(OpCodes.Ret);
             _method.Prepare();
             _redirection.Emit(OpCodes.Call, _method);
             _redirection.Emit(OpCodes.Ret);
             _action.Prepare();
             return _Boundary.Combine(new Advice.Boundary.Advanced.After.Throwing.Singleton(_Method, _action.CreateDelegate(Metadata <Action <object, object[], Exception> > .Type, null) as Action <object, object[], Exception>));
         }
         else
         {
             if (_type == Runtime.Void)
             {
                 _body.BeginExceptionBlock();
                 _body.Emit(_signature, false);
                 _body.Emit(_Pointer, _type, _signature);
                 _body.BeginCatchBlock(Metadata <Exception> .Type);
                 _body.Emit(advice);
                 _body.Emit(OpCodes.Rethrow);
                 _body.EndExceptionBlock();
             }
             else
             {
                 _body.DeclareLocal(_type);
                 _body.BeginExceptionBlock();
                 _body.Emit(_signature, false);
                 _body.Emit(_Pointer, _type, _signature);
                 _body.Emit(OpCodes.Stloc_0);
                 _body.BeginCatchBlock(Metadata <Exception> .Type);
                 _body.Emit(advice);
                 _body.Emit(OpCodes.Rethrow);
                 _body.EndExceptionBlock();
                 _body.Emit(OpCodes.Ldloc_0);
             }
             _body.Emit(OpCodes.Ret);
             _method.Prepare();
             return _method;
         }
     }));
 }
Пример #22
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));
            }));
        }
Пример #23
0
        // We will generate the following code:
        //
        // object ret;
        // object[] args = new object[parameterCount];
        // args[0] = param0;
        // args[1] = param1;
        //  ...
        // try {
        //      ret = handler.Invoke(args);
        // } finally {
        //      param0 = (T0)args[0];   // only generated for each byref argument
        // }
        // return (TRet)ret;
        private static Delegate CreateObjectArrayDelegateRefEmit(Type delegateType, Func <object[], object> handler) // TODO: Test coverage?
        {
            // delegateType must be a delegate type, no check is done
            var delegateInvokeMethod = delegateType.GetMethod("Invoke");

            var returnType     = delegateInvokeMethod.ReturnType;
            var hasReturnValue = returnType != typeof(void);

            var parameters = delegateInvokeMethod.GetParameters();
            var paramTypes = new Type[parameters.Length + 1];

            paramTypes[0] = typeof(Func <object[], object>);
            for (var i = 0; i < parameters.Length; i++)
            {
                paramTypes[i + 1] = parameters[i].ParameterType;
            }

            var thunkMethod = new DynamicMethod("Thunk", returnType, paramTypes);
            var ilgen       = thunkMethod.GetILGenerator();

            var argArray = ilgen.DeclareLocal(typeof(object[]));
            var retValue = ilgen.DeclareLocal(typeof(object));

            // create the argument array
            ilgen.Emit(OpCodes.Ldc_I4, parameters.Length);
            ilgen.Emit(OpCodes.Newarr, typeof(object));
            ilgen.Emit(OpCodes.Stloc, argArray);

            // populate object array
            var hasRefArgs = false;

            for (var i = 0; i < parameters.Length; i++)
            {
                var paramIsByReference = parameters[i].ParameterType.IsByRef;
                var paramType          = parameters[i].ParameterType;
                if (paramIsByReference)
                {
                    paramType = paramType.GetElementType();
                }
                if (paramType == null)
                {
                    throw new ArgumentException("Valid parameter types required");
                }
                hasRefArgs = hasRefArgs || paramIsByReference;

                ilgen.Emit(OpCodes.Ldloc, argArray);
                ilgen.Emit(OpCodes.Ldc_I4, i);
                ilgen.Emit(OpCodes.Ldarg, i + 1);

                if (paramIsByReference)
                {
                    ilgen.Emit(OpCodes.Ldobj, paramType);
                }
                var boxType = ConvertToBoxableType(paramType);
                ilgen.Emit(OpCodes.Box, boxType);
                ilgen.Emit(OpCodes.Stelem_Ref);
            }

            if (hasRefArgs)
            {
                ilgen.BeginExceptionBlock();
            }

            // load delegate
            ilgen.Emit(OpCodes.Ldarg_0);

            // load array
            ilgen.Emit(OpCodes.Ldloc, argArray);

            // invoke Invoke
            var invoke = _funcInvoke;

            ilgen.Emit(OpCodes.Callvirt, invoke);
            ilgen.Emit(OpCodes.Stloc, retValue);

            if (hasRefArgs)
            {
                // copy back ref/out args
                ilgen.BeginFinallyBlock();
                for (var i = 0; i < parameters.Length; i++)
                {
                    if (parameters[i].ParameterType.IsByRef)
                    {
                        var byrefToType = parameters[i].ParameterType.GetElementType();
                        if (byrefToType == null)
                        {
                            throw new ArgumentException("Valid parameter types required");
                        }
                        // update parameter
                        ilgen.Emit(OpCodes.Ldarg, i + 1);
                        ilgen.Emit(OpCodes.Ldloc, argArray);
                        ilgen.Emit(OpCodes.Ldc_I4, i);
                        ilgen.Emit(OpCodes.Ldelem_Ref);
                        ilgen.Emit(OpCodes.Unbox_Any, byrefToType);
                        ilgen.Emit(OpCodes.Stobj, byrefToType);
                    }
                }
                ilgen.EndExceptionBlock();
            }

            if (hasReturnValue)
            {
                ilgen.Emit(OpCodes.Ldloc, retValue);
                ilgen.Emit(OpCodes.Unbox_Any, ConvertToBoxableType(returnType));
            }

            ilgen.Emit(OpCodes.Ret);

            // TODO: we need to cache these.
            return(thunkMethod.CreateDelegate(delegateType, handler));
        }
Пример #24
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)));
        }
Пример #25
0
        /// <summary>
        /// 创建方法
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        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)));
        }
Пример #26
0
        /// <summary> IL构造一个用于执行方法的委托
        /// </summary>
        /// <param name="method">方法</param>
        public static LiteracyCaller CreateCaller(MethodInfo method, Type owner = null)
        {
            if (method == null)
            {
                return(null);
            }

            var dm = new DynamicMethod("", TypeObject, TypesObjectObjects, owner ?? method.DeclaringType, true);

            var il = dm.GetILGenerator();

            var isRef = false;

            var ps = method.GetParameters();

            LocalBuilder[] loc = new LocalBuilder[ps.Length];
            for (int i = 0; i < ps.Length; i++)
            {
                var  p  = ps[i];
                Type pt = p.ParameterType;
                if (pt.IsByRef) //ref,out获取他的实际类型
                {
                    isRef = true;
                    pt    = pt.GetElementType();
                }

                loc[i] = il.DeclareLocal(pt);
                if (p.IsOut == false)
                {
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Ldc_I4, i);
                    il.Emit(OpCodes.Ldelem_Ref);
                    EmitCast(il, pt, false);
                    il.Emit(OpCodes.Stloc, loc[i]); //保存到本地变量
                }
            }

            if (method.IsStatic == false)
            {
                il.Emit(OpCodes.Ldarg_0);
                EmitCast(il, method.DeclaringType);
            }
            //将参数加载到参数堆栈
            foreach (var pa in method.GetParameters())
            {
                if (pa.ParameterType.IsByRef) //out或ref
                {
                    il.Emit(OpCodes.Ldloca_S, loc[pa.Position]);
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, loc[pa.Position]);
                    loc[pa.Position] = null;
                }
            }
            LocalBuilder ret = null;

            if (method.ReturnType != typeof(void))
            {
                ret = il.DeclareLocal(method.ReturnType);
            }

            if (method.IsStatic || method.DeclaringType.IsValueType)
            {
                il.Emit(OpCodes.Call, method);
            }
            else
            {
                il.Emit(OpCodes.Callvirt, method);
            }

            //设置参数
            if (isRef)
            {
                for (int i = 0; i < loc.Length; i++)
                {
                    var l = loc[i];
                    if (l == null)
                    {
                        continue;
                    }
                    il.Emit(OpCodes.Ldarg_1);
                    il.Emit(OpCodes.Ldc_I4, i);
                    il.Emit(OpCodes.Ldloc, l);
                    if (l.LocalType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, l.LocalType);
                    }
                    il.Emit(OpCodes.Stelem_Ref);
                }
            }

            if (ret == null)
            {
                il.Emit(OpCodes.Ldnull);
            }
            else if (method.ReturnType.IsValueType)
            {
                il.Emit(OpCodes.Box, method.ReturnType);
            }
            else
            {
                il.Emit(OpCodes.Castclass, typeof(object));
            }

            il.Emit(OpCodes.Ret);

            return((LiteracyCaller)dm.CreateDelegate(typeof(LiteracyCaller)));
        }
Пример #27
0
        private static void CreateDynamicAssembly()
        {
            // 1. Assert permissions demanded by the DynamicMethod ctor.
            new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Assert(); // BlessedAssert

            // 2. Create the transparent methods, each wrapping a call to a reflection method,
            //    and cache a delegate to each method.
            Type[]        parameterTypes;        // signature of the reflection method
            Type[]        wrappedParameterTypes; // signature of the wrapping method (when different)
            MethodInfo    mi;                    // descriptor for the reflection method
            DynamicMethod method;                // wrapping method
            ILGenerator   il;                    // wrapping method's generator

            // 2a. Delegate.CreateDelegate( Type, Type, String )
            parameterTypes = new Type[] { typeof(Type), typeof(Type), typeof(String) };
            mi             = typeof(Delegate).GetMethod("CreateDelegate", parameterTypes);

            method = new DynamicMethod("CreateDelegate", typeof(Delegate), parameterTypes);
            method.DefineParameter(1, ParameterAttributes.In, "delegateType");
            method.DefineParameter(2, ParameterAttributes.In, "targetType");
            method.DefineParameter(3, ParameterAttributes.In, "methodName");

            il = method.GetILGenerator(5);
            il.Emit(OpCodes.Ldarg_0);               // push delegateType
            il.Emit(OpCodes.Ldarg_1);               // push targetType
            il.Emit(OpCodes.Ldarg_2);               // push methodName
            il.EmitCall(OpCodes.Call, mi, null);    // call Delegate.CreateDelegate
            il.Emit(OpCodes.Ret);                   // return the result

            s_CreateDelegate1 = (CreateDelegate1Delegate)method.CreateDelegate(typeof(CreateDelegate1Delegate));

            // 2b. Delegate.CreateDelegate( Type, Object, String )
            parameterTypes = new Type[] { typeof(Type), typeof(Object), typeof(String) };
            mi             = typeof(Delegate).GetMethod("CreateDelegate", parameterTypes);

            method = new DynamicMethod("CreateDelegate", typeof(Delegate), parameterTypes);
            method.DefineParameter(1, ParameterAttributes.In, "delegateType");
            method.DefineParameter(2, ParameterAttributes.In, "target");
            method.DefineParameter(3, ParameterAttributes.In, "methodName");

            il = method.GetILGenerator(5);
            il.Emit(OpCodes.Ldarg_0);               // push delegateType
            il.Emit(OpCodes.Ldarg_1);               // push target
            il.Emit(OpCodes.Ldarg_2);               // push methodName
            il.EmitCall(OpCodes.Call, mi, null);    // call Delegate.CreateDelegate
            il.Emit(OpCodes.Ret);                   // return the result

            s_CreateDelegate2 = (CreateDelegate2Delegate)method.CreateDelegate(typeof(CreateDelegate2Delegate));

            // 2c. Activator.CreateInstance( Type, Object[] )
            parameterTypes = new Type[] { typeof(Type), typeof(Object[]) };
            mi             = typeof(Activator).GetMethod("CreateInstance", parameterTypes);

            method = new DynamicMethod("CreateInstance", typeof(Object), parameterTypes);
            method.DefineParameter(1, ParameterAttributes.In, "type");
            method.DefineParameter(2, ParameterAttributes.In, "arguments");

            il = method.GetILGenerator(4);
            il.Emit(OpCodes.Ldarg_0);               // push type
            il.Emit(OpCodes.Ldarg_1);               // push arguments
            il.EmitCall(OpCodes.Call, mi, null);    // call Activator.CreateInstance
            il.Emit(OpCodes.Ret);                   // return the result

            s_CreateInstance = (CreateInstanceDelegate)method.CreateDelegate(typeof(CreateInstanceDelegate));

            // 2d. MethodInfo.Invoke(object, args)
            parameterTypes        = new Type[] { typeof(Object), typeof(Object[]) };
            wrappedParameterTypes = new Type[] { typeof(MethodInfo), typeof(Object), typeof(Object[]) };
            mi = typeof(MethodInfo).GetMethod("Invoke", parameterTypes);

            method = new DynamicMethod("InvokeMethod", typeof(Object), wrappedParameterTypes);
            method.DefineParameter(1, ParameterAttributes.In, "method");
            method.DefineParameter(2, ParameterAttributes.In, "instance");
            method.DefineParameter(3, ParameterAttributes.In, "args");

            il = method.GetILGenerator(5);
            il.Emit(OpCodes.Ldarg_0);                // push method
            il.Emit(OpCodes.Ldarg_1);                // push instance
            il.Emit(OpCodes.Ldarg_2);                // push args
            il.EmitCall(OpCodes.Callvirt, mi, null); // call method.Invoke
            il.Emit(OpCodes.Ret);                    // return the result

            s_InvokeMethod = (InvokeMethodDelegate)method.CreateDelegate(typeof(InvokeMethodDelegate));
        }
Пример #28
0
        /// <summary>
        /// 获取方法执行代理
        /// </summary>
        /// <param name="methodInfo"></param>
        /// <returns></returns>
        static FastInvokeHandler GetMethodInvoker(MethodInfo methodInfo)
        {
            DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);
            ILGenerator   il            = dynamicMethod.GetILGenerator();

            ParameterInfo[] ps         = methodInfo.GetParameters();
            Type[]          paramTypes = new Type[ps.Length];
            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    paramTypes[i] = ps[i].ParameterType.GetElementType();
                }
                else
                {
                    paramTypes[i] = ps[i].ParameterType;
                }
            }
            LocalBuilder[] locals = new LocalBuilder[paramTypes.Length];

            for (int i = 0; i < paramTypes.Length; i++)
            {
                locals[i] = il.DeclareLocal(paramTypes[i], true);
            }
            for (int i = 0; i < paramTypes.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_1);
                EmitFastInt(il, i);
                il.Emit(OpCodes.Ldelem_Ref);
                EmitCastToReference(il, paramTypes[i]);
                il.Emit(OpCodes.Stloc, locals[i]);
            }
            if (!methodInfo.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_0);
            }
            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldloca_S, locals[i]);
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, locals[i]);
                }
            }
            if (methodInfo.IsStatic)
            {
                il.EmitCall(OpCodes.Call, methodInfo, null);
            }
            else
            {
                il.EmitCall(OpCodes.Callvirt, methodInfo, null);
            }
            if (methodInfo.ReturnType == typeof(void))
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                EmitBoxIfNeeded(il, methodInfo.ReturnType);
            }

            for (int i = 0; i < paramTypes.Length; i++)
            {
                if (ps[i].ParameterType.IsByRef)
                {
                    il.Emit(OpCodes.Ldarg_1);
                    EmitFastInt(il, i);
                    il.Emit(OpCodes.Ldloc, locals[i]);
                    if (locals[i].LocalType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, locals[i].LocalType);
                    }
                    il.Emit(OpCodes.Stelem_Ref);
                }
            }

            il.Emit(OpCodes.Ret);
            FastInvokeHandler invoder = (FastInvokeHandler)dynamicMethod.CreateDelegate(typeof(FastInvokeHandler));

            return(invoder);
        }
Пример #29
0
    internal static Delegate create_filter_delegate(Delegate dlg, MethodInfo filter_method)
    {
        if (dlg == null)
        {
            throw new ArgumentNullException();
        }
        if (dlg.Target != null)
        {
            throw new ArgumentException();
        }
        if (dlg.Method == null)
        {
            throw new ArgumentException();
        }

        var ret_type    = dlg.Method.ReturnType;
        var param_types = dlg.Method.GetParameters().Select(x => x.ParameterType).ToArray();

        var dynamic = new DynamicMethod(Guid.NewGuid().ToString(), ret_type, param_types, typeof(object), true);
        var ig      = dynamic.GetILGenerator();

        LocalBuilder retval = null;

        if (ret_type != typeof(void))
        {
            retval = ig.DeclareLocal(ret_type);
        }

        var label = ig.BeginExceptionBlock();

        for (int i = 0; i < param_types.Length; i++)
        {
            ig.Emit(OpCodes.Ldarg, i);
        }
        ig.Emit(OpCodes.Call, dlg.Method);

        if (retval != null)
        {
            ig.Emit(OpCodes.Stloc, retval);
        }

        ig.Emit(OpCodes.Leave, label);

        ig.BeginExceptFilterBlock();

        ig.Emit(OpCodes.Call, filter_method);

        ig.BeginCatchBlock(null);

        ig.Emit(OpCodes.Pop);

        ig.EndExceptionBlock();

        if (retval != null)
        {
            ig.Emit(OpCodes.Ldloc, retval);
        }

        ig.Emit(OpCodes.Ret);

        return(dynamic.CreateDelegate(dlg.GetType()));
    }
Пример #30
0
        private static Build CreateBuilder(Type destinationType, IDataRecord dataRecord)
        {
            Build      builder;
            BuilderKey builderKey = new BuilderKey(destinationType, dataRecord);

            if (_builderCache.TryGetValue(builderKey, out builder))
            {
                return(builder);
            }

            var method    = new DynamicMethod("DynamicCreate", destinationType, new[] { typeof(IDataRecord) }, destinationType, true);
            var generator = method.GetILGenerator();

            var result = generator.DeclareLocal(destinationType);

            generator.Emit(OpCodes.Newobj, destinationType.GetConstructor(Type.EmptyTypes));
            generator.Emit(OpCodes.Stloc, result);

            for (var i = 0; i < dataRecord.FieldCount; i++)
            {
                var propertyInfo = destinationType.GetProperty(dataRecord.GetName(i), BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
                var endIfLabel   = generator.DefineLabel();

                if (propertyInfo != null && propertyInfo.GetSetMethod(true) != null)
                {
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, i);
                    generator.Emit(OpCodes.Callvirt, isDBNullMethod);
                    generator.Emit(OpCodes.Brtrue, endIfLabel);

                    generator.Emit(OpCodes.Ldloc, result);
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, i);
                    generator.Emit(OpCodes.Callvirt, getValueMethod);

                    if (propertyInfo.PropertyType.IsGenericType &&
                        propertyInfo.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable <>))
                        )
                    {
                        var nullableType = propertyInfo.PropertyType.GetGenericTypeDefinition().GetGenericArguments()[0];
                        if (!nullableType.IsEnum)
                        {
                            generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
                        }
                        else
                        {
                            generator.Emit(OpCodes.Unbox_Any, nullableType);
                            generator.Emit(OpCodes.Newobj, propertyInfo.PropertyType);
                        }
                    }
                    else
                    {
                        generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));
                    }
                    generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod(true));

                    generator.MarkLabel(endIfLabel);
                }
            }

            generator.Emit(OpCodes.Ldloc, result);
            generator.Emit(OpCodes.Ret);

            builder = (Build)method.CreateDelegate(typeof(Build));
            _builderCache[builderKey] = builder;
            return(builder);
        }
Пример #31
0
 private static T?CreateDelegate <T>(DynamicMethod?method) where T : Delegate =>
 (T?)method?.CreateDelegate(typeof(T));
Пример #32
0
        public override ImmutableCollectionCreator ImmutableDictionaryCreateRange(Type constructingType, Type collectionType, Type elementType)
        {
            Debug.Assert(collectionType.IsGenericType);

            // Only string keys are allowed.
            if (collectionType.GetGenericArguments()[0] != typeof(string))
            {
                throw ThrowHelper.GetNotSupportedException_SerializationNotSupportedCollection(collectionType, parentType: null, memberInfo: null);
            }

            MethodInfo createRange = ImmutableDictionaryCreateRangeMethod(constructingType, elementType);

            if (createRange == null)
            {
                return(null);
            }

            Type creatorType = typeof(ImmutableDictionaryCreator <,>).MakeGenericType(elementType, collectionType);

            ConstructorInfo realMethod = creatorType.GetConstructor(
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                binder: null,
                Type.EmptyTypes,
                modifiers: null);

            Debug.Assert(realMethod != null);

            var dynamicMethod = new DynamicMethod(
                ConstructorInfo.ConstructorName,
                typeof(object),
                Type.EmptyTypes,
                typeof(ReflectionEmitMemberAccessor).Module,
                skipVisibility: true);

            ILGenerator generator = dynamicMethod.GetILGenerator();

            generator.Emit(OpCodes.Newobj, realMethod);
            generator.Emit(OpCodes.Ret);

            JsonClassInfo.ConstructorDelegate constructor = (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate(
                typeof(JsonClassInfo.ConstructorDelegate));

            ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor();

            creator.RegisterCreatorDelegateFromMethod(createRange);
            return(creator);
        }
Пример #33
0
        private static void SetupStateMachineTypeRecursive(
            Dictionary <Type, Dictionary <Type, State> > stateMachinesToStates,
            Dictionary <Type, Dictionary <Type, MethodTable> > stateMachinesToAbstractStates,
            Type stateMachineType)
        {
            Debug.Assert(typeof(StateProvider).IsAssignableFrom(stateMachineType));

            if (stateMachinesToStates.ContainsKey(stateMachineType))
            {
                return;                 // We've already visited this type
            }
            // Recursively process all ancestors, then fetch base type's states
            Dictionary <Type, State>       baseStates         = null;
            Dictionary <Type, MethodTable> baseAbstractStates = null;

            if (stateMachineType != typeof(StateProvider))
            {
                SetupStateMachineTypeRecursive(stateMachinesToStates, stateMachinesToAbstractStates,
                                               stateMachineType.BaseType);
                baseStates         = stateMachinesToStates[stateMachineType.BaseType];
                baseAbstractStates = stateMachinesToAbstractStates[stateMachineType.BaseType];
            }


            // "Used" state methods will be removed from this list, because we want to report errors if any are unused (indicates likely end-user error)
            var stateMethods = stateMachineType
                               .GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |
                                           BindingFlags.DeclaredOnly)
                               .Where(mi => mi.Name.StartsWith("State_")).ToDictionary(mi => mi.Name);


            // Get our method table type:
            Type methodTableType;
            var  methodTableSearchType = stateMachineType;

            while ((methodTableType =
                        methodTableSearchType.GetNestedType("MethodTable", BindingFlags.Public | BindingFlags.NonPublic)
                    ) == null)
            {
                if (!typeof(StateProvider).IsAssignableFrom(methodTableSearchType.BaseType))
                {
                    break;
                }
                methodTableSearchType = methodTableSearchType.BaseType;
            }

            if (methodTableType == null)
            {
                throw new InvalidOperationException("MethodTable not found for " + stateMachineType);
            }
            if (!typeof(MethodTable).IsAssignableFrom(methodTableType))
            {
                throw new InvalidOperationException("MethodTable must be derived from StateMachine.MethodTable");
            }

            // NOTE: There is more correctness checking we could be doing for MethodTable, but it is complicated because
            //       our parent type may be using a grandparent's MethodTable, so the check would have to be recursive.
            //       Instead we just get the type from the parent's State's MethodTable and assume it's correct.


            var states         = new Dictionary <Type, State>();
            var abstractStates = new Dictionary <Type, MethodTable>();

            // Created derived versions of all of our base type's states
            Debug.Assert(baseStates != null == (baseAbstractStates != null));
            if (baseStates != null)
            {
                // This is *not* recursive, because in derived state machines, we want overriding
                // methods to only override the specified state's method - not not *child* states
                // that are specified by the (grand-)parent state machine(s). If we want to follow
                // the state inheritance hierarchy instead, we can do that manually.
                //
                // (I'm guessing this is the best approach. Can always change it later. -AR)

                foreach (var baseState in baseStates)
                {
                    // The state type remains the same, but the method table gets derived
                    var state = (State)Activator.CreateInstance(baseState.Key);
                    state.methodTable =
                        ShallowCloneToDerived(baseState.Value.methodTable, methodTableType, stateMachineType);
                    FillMethodTableWithOverrides(baseState.Key, state.methodTable, stateMachineType, stateMethods);

                    states.Add(baseState.Key, state);
                }

                foreach (var baseAbstractState in baseAbstractStates)
                {
                    // The state type remains the same, but the method table gets derived
                    var methodTable = ShallowCloneToDerived(baseAbstractState.Value, methodTableType, stateMachineType);
                    FillMethodTableWithOverrides(baseAbstractState.Key, methodTable, stateMachineType, stateMethods);

                    abstractStates.Add(baseAbstractState.Key, methodTable);
                }
            }

            // Create state instances for all states declared by the current state machine (recursive to handle state inheritance)
            var newStateTypes = stateMachineType.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic)
                                .Where(nt => typeof(State).IsAssignableFrom(nt)).ToArray();

            foreach (var stateType in newStateTypes)
            {
                SetupStateTypeRecursive(states, abstractStates, stateType, stateMachineType, methodTableType,
                                        stateMethods);
            }


            if (stateMethods.Count > 0)
            {
                Debug.Assert(false);
                throw new Exception("State methods were unused (probably a naming error or undefined state):\n" +
                                    string.Join("\n", stateMethods.Values));
            }


            // Fill in any delegates that are still null with empty methods
            // This is so calling does not require a null check (probably slower due to jump, but makes coding far easier!)
            var stateTypesToMethodTables = states
                                           .Select(kvp => new KeyValuePair <Type, MethodTable>(kvp.Key, kvp.Value.methodTable))
                                           .Concat(abstractStates);

            foreach (var typeToMethodTable in stateTypesToMethodTables)
            {
                var methodTable           = typeToMethodTable.Value;
                var allMethodTableEntries = methodTable.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)
                                            .Where(fi => fi.FieldType.BaseType == typeof(MulticastDelegate));

                foreach (var fieldInfo in allMethodTableEntries)
                {
                    if (fieldInfo.GetCustomAttributes(typeof(AlwaysNullCheckedAttribute), true).Length != 0)
                    {
                        continue;                         // Don't need a default implementation if we promise to always null-check
                    }
                    if (fieldInfo.GetValue(methodTable) == null)
                    {
                        var methodInMethodTable = fieldInfo.FieldType.GetMethod("Invoke");

                        var dynamicMethod = new DynamicMethod(
                            "DoNothing_" + GetStateName(typeToMethodTable.Key) + "_" + fieldInfo.Name,
                            methodInMethodTable.ReturnType,
                            methodInMethodTable.GetParameters().Select(pi => pi.ParameterType).ToArray(),
                            stateMachineType);

                        var il = dynamicMethod.GetILGenerator();
                        EmitDefault(il, methodInMethodTable.ReturnType);
                        il.Emit(OpCodes.Ret);

                        fieldInfo.SetValue(methodTable, dynamicMethod.CreateDelegate(fieldInfo.FieldType));
                    }
                }
            }


            stateMachinesToStates.Add(stateMachineType, states);
            stateMachinesToAbstractStates.Add(stateMachineType, abstractStates);
        }
Пример #34
0
        public override ImmutableCollectionCreator ImmutableCollectionCreateRange(Type constructingType, Type collectionType, Type elementType)
        {
            MethodInfo createRange = ImmutableCollectionCreateRangeMethod(constructingType, elementType);

            if (createRange == null)
            {
                return(null);
            }

            Type creatorType = typeof(ImmutableEnumerableCreator <,>).MakeGenericType(elementType, collectionType);

            ConstructorInfo realMethod = creatorType.GetConstructor(
                BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                binder: null,
                Type.EmptyTypes,
                modifiers: null);

            Debug.Assert(realMethod != null);

            var dynamicMethod = new DynamicMethod(
                ConstructorInfo.ConstructorName,
                typeof(object),
                Type.EmptyTypes,
                typeof(ReflectionEmitMemberAccessor).Module,
                skipVisibility: true);

            ILGenerator generator = dynamicMethod.GetILGenerator();

            generator.Emit(OpCodes.Newobj, realMethod);
            generator.Emit(OpCodes.Ret);

            JsonClassInfo.ConstructorDelegate constructor = (JsonClassInfo.ConstructorDelegate)dynamicMethod.CreateDelegate(
                typeof(JsonClassInfo.ConstructorDelegate));

            ImmutableCollectionCreator creator = (ImmutableCollectionCreator)constructor();

            creator.RegisterCreatorDelegateFromMethod(createRange);
            return(creator);
        }
Пример #35
0
 public override T CreateDelegate <T>(out MethodInfo mi)
 {
     ContractUtils.Requires(typeof(T).IsSubclassOf(typeof(Delegate)), "T");
     mi = _dm;
     return((T)(object)_dm.CreateDelegate(typeof(T), null));
 }
Пример #36
0
        public static Func <A, string> ToString <A>(bool includeBase)
        {
            var isValueType = typeof(A).GetTypeInfo().IsValueType;
            var dynamic     = new DynamicMethod("FieldsToString", typeof(string), new[] { typeof(A) }, true);
            var fields      = GetPublicInstanceFields <A>(
                includeBase,
#pragma warning disable CS0618
                typeof(OptOutOfToStringAttribute),
#pragma warning restore CS0618
                typeof(NonShowAttribute),
                typeof(NonRecordAttribute)
                ).ToArray();
            var stringBuilder = GetConstructor <StringBuilder>().IfNone(() => throw new ArgumentException($"Constructor not found for StringBuilder"));
            var appendChar    = GetPublicInstanceMethod <StringBuilder, char>("Append", true).IfNone(() => throw new ArgumentException($"Append method found for StringBuilder"));
            var appendString  = GetPublicInstanceMethod <StringBuilder, string>("Append", true).IfNone(() => throw new ArgumentException($"Append method found for StringBuilder"));
            var toString      = GetPublicInstanceMethod <Object>("ToString", true).IfNone(() => throw new ArgumentException($"ToString method found for Object"));
            var name          = typeof(A).Name;

            if (name.IndexOf('`') != -1)
            {
                name = name.Split('`').Head();
            }

            var il = dynamic.GetILGenerator();

            il.DeclareLocal(typeof(StringBuilder));
            var notNull = il.DefineLabel();

            if (!isValueType)
            {
                // Check reference == null
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Brtrue_S, notNull);

                // Is null so return "(null)"
                il.Emit(OpCodes.Ldstr, "(null)");
                il.Emit(OpCodes.Ret);

                il.MarkLabel(notNull);
            }

            // var sb = new StringBuilder()
            il.Emit(OpCodes.Newobj, stringBuilder);
            il.Emit(OpCodes.Stloc_0);

            // sb.Append('(')
            il.Emit(OpCodes.Ldloc_0);
            if (fields.Length == 0)
            {
                il.Emit(OpCodes.Ldstr, $"{name}");
            }
            else
            {
                il.Emit(OpCodes.Ldstr, $"{name}(");
            }
            il.Emit(OpCodes.Callvirt, appendString);
            il.Emit(OpCodes.Pop);

            bool first = true;

            foreach (var field in fields)
            {
                var skipAppend = il.DefineLabel();

                if (!first)
                {
                    // sb.Append(", ")
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Ldstr, ", ");
                    il.Emit(OpCodes.Callvirt, appendString);
                    il.Emit(OpCodes.Pop);
                }

                if (!field.FieldType.GetTypeInfo().IsValueType)
                {
                    var fieldNotNull = il.DefineLabel();

                    // If(this.field == null)
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(isValueType ? OpCodes.Ldflda : OpCodes.Ldfld, field);
                    il.Emit(OpCodes.Brtrue_S, fieldNotNull);

                    // sb.Append("null")
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Ldstr, "null");
                    il.Emit(OpCodes.Callvirt, appendString);
                    il.Emit(OpCodes.Pop);

                    // continue
                    il.Emit(OpCodes.Br_S, skipAppend);
                    il.MarkLabel(fieldNotNull);
                }

                il.Emit(OpCodes.Ldloc_0);  // sb
                il.Emit(OpCodes.Ldarg_0);  // this
                il.Emit(isValueType ? OpCodes.Ldflda : OpCodes.Ldfld, field);

                var convertToString = (GetPublicStaticMethod(typeof(Convert), "ToString", field.FieldType) ||
                                       GetPublicStaticMethod(typeof(Convert), "ToString", typeof(object)))
                                      .IfNone(() => throw new Exception());

                if (field.FieldType.GetTypeInfo().IsValueType&& convertToString.GetParameters().Head().ParameterType == typeof(object))
                {
                    il.Emit(OpCodes.Box, field.FieldType);
                }

                il.Emit(convertToString.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, convertToString);

                il.Emit(OpCodes.Callvirt, appendString);
                il.Emit(OpCodes.Pop);
                il.MarkLabel(skipAppend);

                first = false;
            }

            if (fields.Length > 0)
            {
                // Append(')')
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ldc_I4_S, ')');
                il.Emit(OpCodes.Callvirt, appendChar);
                il.Emit(OpCodes.Pop);
            }

            // return sb.ToString()
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Callvirt, toString);
            il.Emit(OpCodes.Ret);

            return((Func <A, string>)dynamic.CreateDelegate(typeof(Func <A, string>)));
        }
Пример #37
0
        /// <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(() =>
            {
                ParamInfo parameter;
                // 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 parameter))
                {
                    parameter.ParameterDirection = parameter.AttachedParam.Direction = ParameterDirection.InputOutput;

                    if (parameter.AttachedParam.Size == 0)
                    {
                        parameter.Size = parameter.AttachedParam.Size = sizeToSet;
                    }
                }
                else
                {
                    SqlMapper.ITypeHandler handler;
                    dbType = (!dbType.HasValue)
#pragma warning disable 618
                    ? SqlMapper.LookupDbType(targetMemberType, targetMemberType.Name, true, out handler)
#pragma warning restore 618
                    : dbType;

                    // CameFromTemplate property would not apply here because this new param
                    // Still needs to be added to the command
                    Add(dynamicParamName, expression.Compile().Invoke(target), null, ParameterDirection.InputOutput, sizeToSet);
                }

                parameter = parameters[dynamicParamName];
                parameter.OutputCallback = setter;
                parameter.OutputTarget   = target;
            });

            return(this);
        }
Пример #38
0
    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]);
    }
Пример #39
0
        public void CreateDelegate_NoMethodBody_ThrowsInvalidOperationException()
        {
            IDClass target = new IDClass();
            DynamicMethod method = new DynamicMethod("Method", typeof(int), new Type[] { typeof(IDClass), typeof(int) }, typeof(IDClass));

            Assert.Throws<InvalidOperationException>(() => method.CreateDelegate(typeof(IntDelegate)));
            Assert.Throws<InvalidOperationException>(() => method.CreateDelegate(typeof(IntDelegate), target));
        }
Пример #40
0
        static TypeAccessor CreateNew(Type type, bool allowNonPublicAccessors)
        {
            if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(type))
            {
                return(DynamicAccessor.Singleton);
            }

            PropertyInfo[]  props  = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            FieldInfo[]     fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            ConstructorInfo ctor   = null;

            if (type.IsClass && !type.IsAbstract)
            {
                ctor = type.GetConstructor(Type.EmptyTypes);
            }
            ILGenerator il;

            if (!IsFullyPublic(type, props, allowNonPublicAccessors))
            {
                DynamicMethod dynGetter = new DynamicMethod(type.FullName + "_get", typeof(object), new Type[] { typeof(object), typeof(string) }, type, true),
                              dynSetter = new DynamicMethod(type.FullName + "_set", null, new Type[] { typeof(object), typeof(string), typeof(object) }, type, true);
                WriteGetter(dynGetter.GetILGenerator(), type, props, fields, true, allowNonPublicAccessors);
                WriteSetter(dynSetter.GetILGenerator(), type, props, fields, true, allowNonPublicAccessors);
                DynamicMethod dynCtor = null;
                if (ctor != null)
                {
                    dynCtor = new DynamicMethod(type.FullName + "_ctor", typeof(object), Type.EmptyTypes, type, true);
                    il      = dynCtor.GetILGenerator();
                    il.Emit(OpCodes.Newobj, ctor);
                    il.Emit(OpCodes.Ret);
                }
                return(new DelegateAccessor(
                           (Func <object, string, object>)dynGetter.CreateDelegate(typeof(Func <object, string, object>)),
                           (Action <object, string, object>)dynSetter.CreateDelegate(typeof(Action <object, string, object>)),
                           dynCtor == null ? null : (Func <object>)dynCtor.CreateDelegate(typeof(Func <object>)), type));
            }

            // note this region is synchronized; only one is being created at a time so we don't need to stress about the builders
            if (assembly == null)
            {
                AssemblyName name = new AssemblyName("FastMember_dynamic");
                assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
                module   = assembly.DefineDynamicModule(name.Name);
            }
            TypeBuilder tb = module.DefineType("FastMember_dynamic." + type.Name + "_" + Interlocked.Increment(ref counter),
                                               (typeof(TypeAccessor).Attributes | TypeAttributes.Sealed | TypeAttributes.Public) & ~(TypeAttributes.Abstract | TypeAttributes.NotPublic), typeof(RuntimeTypeAccessor));

            tb.DefineDefaultConstructor(MethodAttributes.Public);
            PropertyInfo  indexer = typeof(TypeAccessor).GetProperty("Item");
            MethodInfo    baseGetter = indexer.GetGetMethod(), baseSetter = indexer.GetSetMethod();
            MethodBuilder body = tb.DefineMethod(baseGetter.Name, baseGetter.Attributes & ~MethodAttributes.Abstract, typeof(object), new Type[] { typeof(object), typeof(string) });

            il = body.GetILGenerator();
            WriteGetter(il, type, props, fields, false, allowNonPublicAccessors);
            tb.DefineMethodOverride(body, baseGetter);

            body = tb.DefineMethod(baseSetter.Name, baseSetter.Attributes & ~MethodAttributes.Abstract, null, new Type[] { typeof(object), typeof(string), typeof(object) });
            il   = body.GetILGenerator();
            WriteSetter(il, type, props, fields, false, allowNonPublicAccessors);
            tb.DefineMethodOverride(body, baseSetter);

            MethodInfo baseMethod;

            if (ctor != null)
            {
                baseMethod = typeof(TypeAccessor).GetProperty("CreateNewSupported").GetGetMethod();
                body       = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, Type.EmptyTypes);
                il         = body.GetILGenerator();
                il.Emit(OpCodes.Ldc_I4_1);
                il.Emit(OpCodes.Ret);
                tb.DefineMethodOverride(body, baseMethod);

                baseMethod = typeof(TypeAccessor).GetMethod("CreateNew");
                body       = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes, baseMethod.ReturnType, Type.EmptyTypes);
                il         = body.GetILGenerator();
                il.Emit(OpCodes.Newobj, ctor);
                il.Emit(OpCodes.Ret);
                tb.DefineMethodOverride(body, baseMethod);
            }

            baseMethod = typeof(RuntimeTypeAccessor).GetProperty("Type", BindingFlags.NonPublic | BindingFlags.Instance).GetGetMethod(true);
            body       = tb.DefineMethod(baseMethod.Name, baseMethod.Attributes & ~MethodAttributes.Abstract, baseMethod.ReturnType, Type.EmptyTypes);
            il         = body.GetILGenerator();
            il.Emit(OpCodes.Ldtoken, type);
            il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"));
            il.Emit(OpCodes.Ret);
            tb.DefineMethodOverride(body, baseMethod);

            return((TypeAccessor)Activator.CreateInstance(tb.CreateType()));
        }
Пример #41
0
        /// <summary>Find methods from the state machine type to insert into the method table</summary>
        /// <param name="stateMethods">Methods from the state machine type. "Used" methods will be removed.</param>
        private static void FillMethodTableWithOverrides(Type stateType, MethodTable methodTable, Type stateMachineType,
                                                         Dictionary <string, MethodInfo> stateMethods)
        {
            var allMethodTableEntries = methodTable.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)
                                        .Where(fi => fi.FieldType.BaseType == typeof(MulticastDelegate));

            foreach (var fieldInfo in allMethodTableEntries)
            {
                var        potentialMethodName = "State_" + GetStateName(stateType) + "_" + fieldInfo.Name;
                MethodInfo methodInStateMachine;
                if (stateMethods.TryGetValue(potentialMethodName, out methodInStateMachine))
                {
                    var methodInMethodTable = fieldInfo.FieldType.GetMethod("Invoke");


                    // Check the method signatures match...
                    if (methodInStateMachine.ReturnType != methodInMethodTable.ReturnType)
                    {
                        ThrowMethodMismatch(methodInStateMachine, methodInMethodTable);
                    }

                    var methodInMethodTableParameters  = methodInMethodTable.GetParameters();
                    var methodInStateMachineParameters = methodInStateMachine.GetParameters();

                    if (methodInStateMachineParameters.Length != methodInMethodTableParameters.Length - 1
                        )                 // -1 to account for 'this' parameter to open delegate
                    {
                        ThrowMethodMismatch(methodInStateMachine, methodInMethodTable);
                    }

                    for (var i = 0; i < methodInStateMachineParameters.Length; i++)
                    {
                        if (methodInStateMachineParameters[i].ParameterType !=
                            methodInMethodTableParameters[i + 1]
                            .ParameterType &&                                 // +1 to account for 'this' parameter to open delegate
                            !methodInMethodTableParameters[i + 1].ParameterType
                            .IsAssignableFrom(methodInStateMachineParameters[i].ParameterType)
                            )                     // i.e. supports custom implementations of IUpdateContext
                        {
                            ThrowMethodMismatch(methodInStateMachine, methodInMethodTable);
                        }
                    }


                    // Check whether we need a down-casting shim (because the method was declared for a base type of the current stateMachineType)
                    if (!stateMachineType.IsAssignableFrom(methodInMethodTableParameters[0].ParameterType))
                    {
                        Debug.Assert(methodInMethodTableParameters[0].ParameterType
                                     .IsAssignableFrom(stateMachineType));                    // (other direction)

                        var dynamicMethod = new DynamicMethod("CastingShim_" + potentialMethodName,
                                                              methodInMethodTable.ReturnType,
                                                              methodInMethodTableParameters.Select(pi => pi.ParameterType).ToArray(), stateMachineType);
                        var il = dynamicMethod.GetILGenerator();
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Castclass, stateMachineType);                         // <- the casting bit of the shim
                        if (methodInMethodTableParameters.Length > 1)
                        {
                            il.Emit(OpCodes.Ldarg_1);
                        }
                        if (methodInMethodTableParameters.Length > 2)
                        {
                            il.Emit(OpCodes.Ldarg_2);
                        }
                        if (methodInMethodTableParameters.Length > 3)
                        {
                            il.Emit(OpCodes.Ldarg_3);
                        }
                        for (var i = 4; i < methodInMethodTableParameters.Length; i++)
                        {
                            if (i <= byte.MaxValue)
                            {
                                il.Emit(OpCodes.Ldarg_S, (byte)i);
                            }
                            else
                            {
                                il.Emit(OpCodes.Ldarg, (ushort)i);
                            }
                        }
                        il.Emit(OpCodes.Callvirt, methodInStateMachine);                         // <- the call forwarding bit of the shim
                        il.Emit(OpCodes.Ret);

                        fieldInfo.SetValue(methodTable, dynamicMethod.CreateDelegate(fieldInfo.FieldType));
                    }
                    else
                    {
                        // No shim required, create an open delegate
                        fieldInfo.SetValue(methodTable,
                                           Delegate.CreateDelegate(fieldInfo.FieldType, methodInStateMachine));
                    }

                    stateMethods.Remove(potentialMethodName);
                }
            }
        }
        /// <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));
        }
        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));
        }
Пример #44
0
        public static bool TryGetAssessors(MethodInfo getMethod, MethodInfo setMethod, out Func <object, object> getFn, out Action <object, object> setFn)
        {
            getFn = null;
            setFn = null;

            if (AotRuntime)
            {
                return(false);
            }

            if (getMethod != null && !getMethod.IsStatic && getMethod.GetParameters().Length == 0)
            {
                lock (ReadFunctions)
                {
                    if (ReadFunctions.TryGetValue(getMethod, out getFn) == false)
                    {
                        var instanceParam = Expression.Parameter(typeof(object), "instance");
                        var declaringType = getMethod.DeclaringType;
                        Debug.Assert(declaringType != null, "getMethodDeclaringType != null");
                        getFn = Expression.Lambda <Func <object, object> >(
                            Expression.Convert(
                                Expression.Call(
                                    Expression.Convert(instanceParam, declaringType), getMethod),
                                typeof(object)),
                            instanceParam
                            ).Compile();
                        ReadFunctions.Add(getMethod, getFn);
                    }
                }
            }

            if (setMethod != null && !setMethod.IsStatic && setMethod.GetParameters().Length == 1)
            {
                lock (WriteFunctions)
                {
                    if (WriteFunctions.TryGetValue(setMethod, out setFn) == false)
                    {
                        var declaringType  = setMethod.DeclaringType;
                        var valueParameter = setMethod.GetParameters().Single();
                        Debug.Assert(declaringType != null, "getMethodDeclaringType != null");
                        var setDynamicMethod = new DynamicMethod(declaringType.FullName + "::" + setMethod.Name, typeof(void), new Type[] { typeof(object), typeof(object) }, restrictedSkipVisibility: true);
                        var il = setDynamicMethod.GetILGenerator();

                        if (declaringType.IsValueType)
                        {
                            il.Emit(OpCodes.Ldarg_0);                             // instance
                            il.Emit(OpCodes.Mkrefany, declaringType);             // typed ref with instance
                            il.Emit(OpCodes.Refanyval, declaringType);            // &instance
                            il.Emit(OpCodes.Ldarg_1);                             // value
                            if (valueParameter.ParameterType.IsValueType)
                            {
                                il.Emit(OpCodes.Unbox_Any, valueParameter.ParameterType);
                            }
                            else
                            {
                                il.Emit(OpCodes.Castclass, valueParameter.ParameterType);
                            }
                            il.Emit(OpCodes.Callvirt, setMethod);                             // call instance.Set(value)
                            il.Emit(OpCodes.Ret);
                        }
                        else
                        {
                            il.Emit(OpCodes.Ldarg_0);                             // instance
                            il.Emit(OpCodes.Castclass, declaringType);
                            il.Emit(OpCodes.Ldarg_1);                             // value
                            if (valueParameter.ParameterType.IsValueType)
                            {
                                il.Emit(OpCodes.Unbox_Any, valueParameter.ParameterType);
                            }
                            else
                            {
                                il.Emit(OpCodes.Castclass, valueParameter.ParameterType);
                            }
                            il.Emit(OpCodes.Callvirt, setMethod);                             // call instance.Set(value)
                            il.Emit(OpCodes.Ret);
                        }
                        setFn = (Action <object, object>)setDynamicMethod.CreateDelegate(typeof(Action <object, object>));
                        WriteFunctions.Add(setMethod, setFn);
                    }
                }
            }

            return(true);
        }
Пример #45
0
            protected override 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 (_reflectionInfo.DeclaringType.IsValueType)
                {
                    var local = ilGen.DeclareLocal(_reflectionInfo.DeclaringType);
                    ilGen.Emit(OpCodes.Stloc, local);
                    ilGen.Emit(OpCodes.Ldloca, local);
                }

                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.Call, _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>)));
                }
            }
Пример #46
0
        public ObserverGrain()
        {
            GrainType  = GetType();
            concurrent = typeof(IConcurrentObserver).IsAssignableFrom(GrainType);
            var handlerAttributes = GrainType.GetCustomAttributes(typeof(HandlerAttribute), false);

            if (handlerAttributes.Length > 0)
            {
                handlerAttribute = (HandlerAttribute)handlerAttributes[0];
            }
            else
            {
                handlerAttribute = default;
            }
            var methods = GetType().GetMethods().Where(m =>
            {
                var parameters = m.GetParameters();
                return(parameters.Length >= 1 && parameters.Any(p => typeof(IEvent).IsAssignableFrom(p.ParameterType)));
            }).ToList();
            var dynamicMethod = new DynamicMethod($"Handler_Invoke", typeof(Task), new Type[] { typeof(object), typeof(IEvent), typeof(EventBase) }, GrainType, true);
            var ilGen         = dynamicMethod.GetILGenerator();
            var items         = new List <SwitchMethodEmit>();

            for (int i = 0; i < methods.Count; i++)
            {
                var method       = methods[i];
                var methodParams = method.GetParameters();
                var caseType     = methodParams.Single(p => typeof(IEvent).IsAssignableFrom(p.ParameterType)).ParameterType;
                items.Add(new SwitchMethodEmit
                {
                    Mehod        = method,
                    CaseType     = caseType,
                    DeclareLocal = ilGen.DeclareLocal(caseType),
                    Lable        = ilGen.DefineLabel(),
                    Parameters   = methodParams,
                    Index        = i
                });
            }
            var defaultLabel = ilGen.DefineLabel();
            var lastLable    = ilGen.DefineLabel();
            var declare_1    = ilGen.DeclareLocal(typeof(Task));

            foreach (var item in items)
            {
                ilGen.Emit(OpCodes.Ldarg_1);
                ilGen.Emit(OpCodes.Isinst, item.CaseType);
                if (item.Index > 3)
                {
                    ilGen.Emit(OpCodes.Stloc_S, item.DeclareLocal);
                    ilGen.Emit(OpCodes.Ldloc_S, item.DeclareLocal);
                }
                else
                {
                    if (item.Index == 0)
                    {
                        ilGen.Emit(OpCodes.Stloc_0);
                        ilGen.Emit(OpCodes.Ldloc_0);
                    }
                    else if (item.Index == 1)
                    {
                        ilGen.Emit(OpCodes.Stloc_1);
                        ilGen.Emit(OpCodes.Ldloc_1);
                    }
                    else if (item.Index == 2)
                    {
                        ilGen.Emit(OpCodes.Stloc_2);
                        ilGen.Emit(OpCodes.Ldloc_2);
                    }
                    else
                    {
                        ilGen.Emit(OpCodes.Stloc_3);
                        ilGen.Emit(OpCodes.Ldloc_3);
                    }
                }

                ilGen.Emit(OpCodes.Brtrue_S, item.Lable);
            }
            ilGen.Emit(OpCodes.Br_S, defaultLabel);
            foreach (var item in items)
            {
                ilGen.MarkLabel(item.Lable);
                ilGen.Emit(OpCodes.Ldarg_0);
                //加载第一个参数
                if (item.Parameters[0].ParameterType == item.CaseType)
                {
                    LdEventArgs(item, ilGen);
                }
                else if (item.Parameters[0].ParameterType == typeof(EventBase))
                {
                    ilGen.Emit(OpCodes.Ldarg_2);
                }
                //加载第二个参数
                if (item.Parameters.Length == 2)
                {
                    if (item.Parameters[1].ParameterType == item.CaseType)
                    {
                        LdEventArgs(item, ilGen);
                    }
                    else if (item.Parameters[1].ParameterType == typeof(EventBase))
                    {
                        ilGen.Emit(OpCodes.Ldarg_2);
                    }
                }
                ilGen.Emit(OpCodes.Call, item.Mehod);
                ilGen.Emit(OpCodes.Stloc_S, declare_1);
                ilGen.Emit(OpCodes.Br_S, lastLable);
            }
            ilGen.MarkLabel(defaultLabel);
            ilGen.Emit(OpCodes.Ldarg_0);
            ilGen.Emit(OpCodes.Ldarg_1);
            ilGen.Emit(OpCodes.Call, GrainType.GetMethod(nameof(DefaultHandler)));
            ilGen.Emit(OpCodes.Stloc_S, declare_1);
            ilGen.Emit(OpCodes.Br_S, lastLable);
            //last
            ilGen.MarkLabel(lastLable);
            ilGen.Emit(OpCodes.Ldloc_S, declare_1);
            ilGen.Emit(OpCodes.Ret);
            handlerInvokeFunc = (Func <object, IEvent, EventBase, Task>)dynamicMethod.CreateDelegate(typeof(Func <object, IEvent, EventBase, Task>));
Пример #47
0
        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));
        }
Пример #48
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(s_runCache[delegateType] = (Func <LightLambda, Delegate>)ctorMethod.CreateDelegate(typeof(Func <LightLambda, Delegate>)));
                }

                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(s_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(s_runCache[delegateType] = lambda => targetMethod.CreateDelegate(delegateType, lambda));
        }
Пример #49
0
        public static bool TryGetAssessors(FieldInfo fieldInfo, out Func <object, object> getFn, out Action <object, object> setFn)
        {
            getFn = null;
            setFn = null;

            if (AotRuntime || fieldInfo.IsStatic)
            {
                return(false);
            }


            lock (ReadFunctions)
            {
                if (ReadFunctions.TryGetValue(fieldInfo, out getFn) == false)
                {
                    var instanceParam = Expression.Parameter(typeof(object), "instance");
                    var declaringType = fieldInfo.DeclaringType;
                    Debug.Assert(declaringType != null, "getMethodDeclaringType != null");
                    getFn = Expression.Lambda <Func <object, object> >(
                        Expression.Convert(
                            Expression.Field(
                                Expression.Convert(instanceParam, declaringType),
                                fieldInfo),
                            typeof(object)),
                        instanceParam
                        ).Compile();
                    ReadFunctions.Add(fieldInfo, getFn);
                }
            }

            if (fieldInfo.IsInitOnly == false)
            {
                lock (WriteFunctions)
                {
                    if (WriteFunctions.TryGetValue(fieldInfo, out setFn) == false)
                    {
                        var declaringType = fieldInfo.DeclaringType;
                        var fieldType     = fieldInfo.FieldType;
                        Debug.Assert(declaringType != null, "getMethodDeclaringType != null");
                        var setDynamicMethod = new DynamicMethod(declaringType.FullName + "::" + fieldInfo.Name, typeof(void), new Type[] { typeof(object), typeof(object) }, restrictedSkipVisibility: true);
                        var il = setDynamicMethod.GetILGenerator();

                        if (declaringType.IsValueType)
                        {
                            il.Emit(OpCodes.Ldarg_0);                             // instance
                            il.Emit(OpCodes.Mkrefany, declaringType);             // typed ref with instance
                            il.Emit(OpCodes.Refanyval, declaringType);            // &instance
                            il.Emit(OpCodes.Ldarg_1);                             // value
                            if (fieldType.IsValueType)
                            {
                                il.Emit(OpCodes.Unbox_Any, fieldType);
                            }
                            else
                            {
                                il.Emit(OpCodes.Castclass, fieldType);
                            }
                            il.Emit(OpCodes.Stfld, fieldInfo);                             // call instance.Set(value)
                            il.Emit(OpCodes.Ret);
                        }
                        else
                        {
                            il.Emit(OpCodes.Ldarg_0);                             // instance
                            il.Emit(OpCodes.Castclass, declaringType);
                            il.Emit(OpCodes.Ldarg_1);                             // value
                            if (fieldType.IsValueType)
                            {
                                il.Emit(OpCodes.Unbox_Any, fieldType);
                            }
                            else
                            {
                                il.Emit(OpCodes.Castclass, fieldType);
                            }
                            il.Emit(OpCodes.Stfld, fieldInfo);                             // call instance.Set(value)
                            il.Emit(OpCodes.Ret);
                        }
                        setFn = (Action <object, object>)setDynamicMethod.CreateDelegate(typeof(Action <object, object>));
                        WriteFunctions.Add(fieldInfo, setFn);
                    }
                }
            }

            return(true);
        }
Пример #50
0
        /// <summary>
        /// Creates a Func that extracts parameters from the given type for use by a LuaScript.
        ///
        /// Members that are RedisKey's get extracted to be passed in as keys to redis; all members that
        /// appear in the script get extracted as RedisValue arguments to be sent up as args.
        ///
        /// We send all values as arguments so we don't have to prepare the same script for different parameter
        /// types.
        ///
        /// The created Func takes a RedisKey, which will be prefixed to all keys (and arguments of type RedisKey) for
        /// keyspace isolation.
        /// </summary>
        public static Func <object, RedisKey?, ScriptParameters> GetParameterExtractor(Type t, LuaScript script)
        {
            string ignored;

            if (!IsValidParameterHash(t, script, out ignored, out ignored))
            {
                throw new Exception("Shouldn't be possible");
            }

            var keys = new List <MemberInfo>();
            var args = new List <MemberInfo>();

            for (var i = 0; i < script.Arguments.Length; i++)
            {
                var argName = script.Arguments[i];
                var member  = t.GetMember(argName).SingleOrDefault(m => m is PropertyInfo || m is FieldInfo);

                var memberType = member is FieldInfo ? ((FieldInfo)member).FieldType : ((PropertyInfo)member).PropertyType;

                if (memberType == typeof(RedisKey))
                {
                    keys.Add(member);
                }

                args.Add(member);
            }

            var nullableRedisKeyHasValue = typeof(RedisKey?).GetProperty("HasValue").GetGetMethod();

            var dyn = new DynamicMethod("ParameterExtractor_" + t.FullName + "_" + script.OriginalScript.GetHashCode(), typeof(ScriptParameters), new[] { typeof(object), typeof(RedisKey?) }, restrictedSkipVisibility: true);
            var il  = dyn.GetILGenerator();

            // only init'd if we use it
            LocalBuilder redisKeyLoc = null;
            var          loc         = il.DeclareLocal(t);

            il.Emit(OpCodes.Ldarg_0);               // object
#if !CORE_CLR
            if (t.IsValueType)
#else
            if (t.GetTypeInfo().IsValueType)
#endif
            {
                il.Emit(OpCodes.Unbox_Any, t);      // T
            }
            else
            {
                il.Emit(OpCodes.Castclass, t);      // T
            }
            il.Emit(OpCodes.Stloc, loc);            // --empty--

            var needsKeyPrefixLoc = il.DeclareLocal(typeof(bool));

            il.Emit(OpCodes.Ldarga_S, 1);                       // RedisKey?*
            il.Emit(OpCodes.Call, nullableRedisKeyHasValue);    // bool
            il.Emit(OpCodes.Stloc, needsKeyPrefixLoc);          // --empty--

            if (keys.Count == 0)
            {
                // if there are no keys, don't allocate
                il.Emit(OpCodes.Ldnull);                    // null
            }
            else
            {
                il.Emit(OpCodes.Ldc_I4, keys.Count);        // int
                il.Emit(OpCodes.Newarr, typeof(RedisKey));  // RedisKey[]
            }

            for (var i = 0; i < keys.Count; i++)
            {
                il.Emit(OpCodes.Dup);                       // RedisKey[] RedisKey[]
                il.Emit(OpCodes.Ldc_I4, i);                 // RedisKey[] RedisKey[] int
#if !CORE_CLR
                if (t.IsValueType)
#else
                if (t.GetTypeInfo().IsValueType)
#endif
                {
                    il.Emit(OpCodes.Ldloca, loc);           // RedisKey[] RedisKey[] int T*
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, loc);                        // RedisKey[] RedisKey[] int T
                }
                LoadMember(il, keys[i]);                                // RedisKey[] RedisKey[] int RedisKey
                PrefixIfNeeded(il, needsKeyPrefixLoc, ref redisKeyLoc); // RedisKey[] RedisKey[] int RedisKey
                il.Emit(OpCodes.Stelem, typeof(RedisKey));              // RedisKey[]
            }

            if (args.Count == 0)
            {
                // if there are no args, don't allocate
                il.Emit(OpCodes.Ldnull);                        // RedisKey[] null
            }
            else
            {
                il.Emit(OpCodes.Ldc_I4, args.Count);            // RedisKey[] int
                il.Emit(OpCodes.Newarr, typeof(RedisValue));    // RedisKey[] RedisValue[]
            }

            for (var i = 0; i < args.Count; i++)
            {
                il.Emit(OpCodes.Dup);                       // RedisKey[] RedisValue[] RedisValue[]
                il.Emit(OpCodes.Ldc_I4, i);                 // RedisKey[] RedisValue[] RedisValue[] int
#if !CORE_CLR
                if (t.IsValueType)
#else
                if (t.GetTypeInfo().IsValueType)
#endif
                {
                    il.Emit(OpCodes.Ldloca, loc);           // RedisKey[] RedisValue[] RedisValue[] int T*
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, loc);            // RedisKey[] RedisValue[] RedisValue[] int T
                }

                var member = args[i];
                LoadMember(il, member);                                              // RedisKey[] RedisValue[] RedisValue[] int memberType
                ConvertToRedisValue(member, il, needsKeyPrefixLoc, ref redisKeyLoc); // RedisKey[] RedisValue[] RedisValue[] int RedisValue

                il.Emit(OpCodes.Stelem, typeof(RedisValue));                         // RedisKey[] RedisValue[]
            }

            il.Emit(OpCodes.Newobj, ScriptParameters.Cons); // ScriptParameters
            il.Emit(OpCodes.Ret);                           // --empty--

            var ret = (Func <object, RedisKey?, ScriptParameters>)dyn.CreateDelegate(typeof(Func <object, RedisKey?, ScriptParameters>));

            return(ret);
        }