private static LocalBuilder[] EmitLoadParameters(DelegateBuildInfo info, ILGenerator il, int argumentArrayIndex)
        {
            if (!info.Method.IsStatic && !(info.Method is ConstructorInfo))
            {
                il.Emit(OpCodes.Ldarg_0);
                EmitUnboxOrCast(il, info.Method.DeclaringType);
            }

            var locals     = new LocalBuilder[info.RefParameterIndexes.Count];
            var localIndex = 0;

            for (int index = 0; index < info.Parameters.Length; index++)
            {
                if (!info.Parameters[index].IsOut)
                {
                    EmitLoadArg(il, argumentArrayIndex);
                    EmitLoadInt(il, index);
                    il.Emit(OpCodes.Ldelem_Ref);
                    EmitUnboxOrCast(il, info.ParameterTypes[index]);
                    if (info.Parameters[index].ParameterType.IsByRef)
                    {
                        locals[localIndex] = il.DeclareLocal(info.ParameterTypes[index], true);
                        il.Emit(OpCodes.Stloc, locals[localIndex]);
                        il.Emit(OpCodes.Ldloca_S, locals[localIndex++]);
                    }
                }
                else
                {
                    locals[localIndex] = il.DeclareLocal(info.ParameterTypes[index], true);
                    il.Emit(OpCodes.Ldloca_S, locals[localIndex++]);
                }
            }

            return(locals);
        }
        /// <summary>
        /// Creates a new <see cref="Invoker"/> that calls the specified method in a
        /// late-bound manner.
        /// </summary>
        /// <param name="method">The method that the invoker should call.</param>
        /// <returns>A dynamic invoker that can call the specified method.</returns>
        public static Invoker CreateInvoker(MethodInfo method)
        {
            DynamicMethod callable = CreateDynamicInvoker();
            var info = new DelegateBuildInfo(method);

            ILGenerator il = callable.GetILGenerator();

            EmitCheckParameters(info, il, 1);
            var locals = EmitLoadParameters(info, il, 1);

            il.EmitCall(method.IsStatic ? OpCodes.Call : OpCodes.Callvirt, method, null);

            if (method.ReturnType == typeof(void))
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                if (info.ReturnType.IsValueType)
                {
                    il.Emit(OpCodes.Box, method.ReturnType);
                }
            }

            EmitReturnRefValues(info, il, locals);

            il.Emit(OpCodes.Ret);
            return callable.CreateDelegate(typeof(Invoker)) as Invoker;
        }
Ejemplo n.º 3
0
        /*----------------------------------------------------------------------------------------*/
        #region Public Methods
        /// <summary>
        /// Creates a new <see cref="Invoker"/> that calls the specified method in a
        /// late-bound manner.
        /// </summary>
        /// <param name="method">The method that the invoker should call.</param>
        /// <returns>A dynamic invoker that can call the specified method.</returns>
        public static Invoker CreateInvoker(MethodInfo method)
        {
            DynamicMethod callable = CreateDynamicInvoker();
            var           info     = new DelegateBuildInfo(method);

            ILGenerator il = callable.GetILGenerator();

            EmitCheckParameters(info, il, 1);
            EmitLoadParameters(info, il, 1);

            if (method.IsStatic)
            {
                il.EmitCall(OpCodes.Call, method, null);
            }
            else
            {
                il.EmitCall(OpCodes.Callvirt, method, null);
            }

            if (method.ReturnType == typeof(void))
            {
                il.Emit(OpCodes.Ldnull);
            }
            else
            {
                if (info.ReturnType.IsValueType)
                {
                    il.Emit(OpCodes.Box, method.ReturnType);
                }
            }

            il.Emit(OpCodes.Ret);

            return(callable.CreateDelegate(typeof(Invoker)) as Invoker);
        }
Ejemplo n.º 4
0
        /*----------------------------------------------------------------------------------------*/
        #region Private Methods: Utility
        private static void EmitCheckParameters(DelegateBuildInfo info, ILGenerator il, int argumentArrayIndex)
        {
            Label beginLabel = il.DefineLabel();

            EmitLoadArg(il, argumentArrayIndex);
            il.Emit(OpCodes.Ldlen);
            EmitLoadInt(il, info.Parameters.Length);
            il.Emit(OpCodes.Beq, beginLabel);

            il.Emit(OpCodes.Newobj, TargetParameterCountExceptionConstructor);
            il.Emit(OpCodes.Throw);

            il.MarkLabel(beginLabel);
        }
        private static void EmitReturnRefValues(DelegateBuildInfo info, ILGenerator il, LocalBuilder[] locals)
        {
            for (int i = 0; i < locals.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_1);
                EmitLoadInt(il, info.RefParameterIndexes[i]);
                il.Emit(OpCodes.Ldloc, locals[i]);
                if (locals[i].LocalType.IsValueType)
                {
                    il.Emit(OpCodes.Box, locals[i].LocalType);
                }

                il.Emit(OpCodes.Stelem_Ref);
            }
        }
Ejemplo n.º 6
0
        /*----------------------------------------------------------------------------------------*/
        private static void EmitLoadParameters(DelegateBuildInfo info, ILGenerator il, int argumentArrayIndex)
        {
            if (!info.Method.IsStatic && !(info.Method is ConstructorInfo))
            {
                il.Emit(OpCodes.Ldarg_0);
                EmitUnboxOrCast(il, info.Method.DeclaringType);
            }

            for (int index = 0; index < info.Parameters.Length; index++)
            {
                EmitLoadArg(il, argumentArrayIndex);
                EmitLoadInt(il, index);
                il.Emit(OpCodes.Ldelem_Ref);
                EmitUnboxOrCast(il, info.ParameterTypes[index]);
            }
        }
        /// <summary>
        /// Creates a new <see cref="FactoryMethod"/> that calls the specified constructor in a
        /// late-bound manner.
        /// </summary>
        /// <param name="constructor">The constructor that the factory method should call.</param>
        /// <returns>A dynamic factory method that can call the specified constructor.</returns>
        public static FactoryMethod CreateFactoryMethod(ConstructorInfo constructor)
        {
            DynamicMethod callable = CreateDynamicFactoryMethod();
            var           info     = new DelegateBuildInfo(constructor);

            Type        returnType = constructor.ReflectedType;
            ILGenerator il         = callable.GetILGenerator();

            EmitCheckParameters(info, il, 0);
            EmitLoadParameters(info, il, 0);

            il.Emit(OpCodes.Newobj, constructor);

            if (info.ReturnType.IsValueType)
            {
                il.Emit(OpCodes.Box, returnType);
            }

            il.Emit(OpCodes.Ret);
            return(callable.CreateDelegate(typeof(FactoryMethod)) as FactoryMethod);
        }
        /// <summary>
        /// Creates a new <see cref="FactoryMethod"/> that calls the specified constructor in a
        /// late-bound manner.
        /// </summary>
        /// <param name="constructor">The constructor that the factory method should call.</param>
        /// <returns>A dynamic factory method that can call the specified constructor.</returns>
        public static FactoryMethod CreateFactoryMethod(ConstructorInfo constructor)
        {
            DynamicMethod callable = CreateDynamicFactoryMethod();
            var info = new DelegateBuildInfo(constructor);

            Type returnType = constructor.ReflectedType;
            ILGenerator il = callable.GetILGenerator();

            EmitCheckParameters(info, il, 0);
            EmitLoadParameters(info, il, 0);

            il.Emit(OpCodes.Newobj, constructor);

            if (info.ReturnType.IsValueType)
            {
                il.Emit(OpCodes.Box, returnType);
            }

            il.Emit(OpCodes.Ret);
            return callable.CreateDelegate(typeof(FactoryMethod)) as FactoryMethod;
        }
        private static void EmitReturnRefValues(DelegateBuildInfo info, ILGenerator il, LocalBuilder[] locals)
        {
            for (int i = 0; i < locals.Length; i++)
            {
                il.Emit(OpCodes.Ldarg_1);
                EmitLoadInt(il, info.RefParameterIndexes[i]);
                il.Emit(OpCodes.Ldloc, locals[i]);
                if (locals[i].LocalType.IsValueType)
                {
                    il.Emit(OpCodes.Box, locals[i].LocalType);
                }

                il.Emit(OpCodes.Stelem_Ref);
            }
        }
        private static LocalBuilder[] EmitLoadParameters(DelegateBuildInfo info, ILGenerator il, int argumentArrayIndex)
        {
            if (!info.Method.IsStatic && !(info.Method is ConstructorInfo))
            {
                il.Emit(OpCodes.Ldarg_0);
                EmitUnboxOrCast(il, info.Method.DeclaringType);
            }

            var locals = new LocalBuilder[info.RefParameterIndexes.Count];
            var localIndex = 0;
            for (int index = 0; index < info.Parameters.Length; index++)
            {
                EmitLoadArg(il, argumentArrayIndex);
                EmitLoadInt(il, index);
                il.Emit(OpCodes.Ldelem_Ref);
                EmitUnboxOrCast(il, info.ParameterTypes[index]);
                if (info.Parameters[index].ParameterType.IsByRef)
                {
                    locals[localIndex] = il.DeclareLocal(info.ParameterTypes[index], true);
                    il.Emit(OpCodes.Stloc, locals[localIndex]);
                    il.Emit(OpCodes.Ldloca_S, locals[localIndex++]);
                }
            }

            return locals;
        }
        private static void EmitCheckParameters(DelegateBuildInfo info, ILGenerator il, int argumentArrayIndex)
        {
            Label beginLabel = il.DefineLabel();

            EmitLoadArg(il, argumentArrayIndex);
            il.Emit(OpCodes.Ldlen);
            EmitLoadInt(il, info.Parameters.Length);
            il.Emit(OpCodes.Beq, beginLabel);

            il.Emit(OpCodes.Newobj, TargetParameterCountExceptionConstructor);
            il.Emit(OpCodes.Throw);

            il.MarkLabel(beginLabel);
        }
Ejemplo n.º 12
0
		/*----------------------------------------------------------------------------------------*/
		private static void EmitLoadParameters(DelegateBuildInfo info, ILGenerator il, int argumentArrayIndex)
		{
			if (!info.Method.IsStatic && !(info.Method is ConstructorInfo))
			{
				il.Emit(OpCodes.Ldarg_0);
				EmitUnboxOrCast(il, info.Method.DeclaringType);
			}

			for (int index = 0; index < info.Parameters.Length; index++)
			{
				EmitLoadArg(il, argumentArrayIndex);
				EmitLoadInt(il, index);
				il.Emit(OpCodes.Ldelem_Ref);
				EmitUnboxOrCast(il, info.ParameterTypes[index]);
			}
		}