Example #1
0
 public static DynamicMethod MulBy2AndAdd1()
 {
     var f = DynamicMethod("MultiplyBy2AndAdd1", typeof(int), new[] { typeof(int) },
                           typeof(DynamicMethodUsingMSIL).Module);
     OneParameter <int, int> invokeSquareIt =
         (OneParameter <int, int>)
         f.CreateDelegate(typeof(OneParameter <int, int>));
 }
Example #2
0
        private static int TestSDivision(int divisions, int invokes)
        {
            int    i, j;
            Random rand = new Random();

            for (i = 0; i < divisions; i++)
            {
                int divisor = rand.Next(Int32.MinValue, Int32.MaxValue);

                if (divisor == 0 || divisor == -1)
                {
                    continue;
                }

                DynamicMethod SDivision = new DynamicMethod(
                    String.Format("SDivision{0}", i),
                    typeof(int),
                    SDivisionArgs,
                    typeof(T).Module);

                ILGenerator il = SDivision.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldc_I4, divisor);
                il.Emit(OpCodes.Div);
                il.Emit(OpCodes.Ret);

                OneParameter <int, int> invokeSDivision =
                    (OneParameter <int, int>)
                    SDivision.CreateDelegate(typeof(OneParameter <int, int>));

                for (j = 0; j < invokes; j++)
                {
                    int dividend = rand.Next(Int32.MinValue, Int32.MaxValue);
                    int result, expected;

                    result   = invokeSDivision(dividend);
                    expected = dividend / divisor;

                    if (result != expected)
                    {
                        Console.WriteLine("{0} / {1} = {2} != {3})", dividend, divisor, expected, result);
                        return(-1);
                    }
                }
            }

            return(0);
        }
Example #3
0
        void StartDynamicMethod()
        {
            Type[]        methodArgs = { typeof(int) };
            DynamicMethod squareIt   = new DynamicMethod("SquareIt", typeof(long), methodArgs, typeof(Program).Module);
            ILGenerator   il         = squareIt.GetILGenerator();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Conv_I8);
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Mul);
            il.Emit(OpCodes.Ret);
            OneParameter <long, int> invokeSquareIt = (OneParameter <long, int>)squareIt.CreateDelegate(typeof(OneParameter <long, int>));
            var result = invokeSquareIt(42);

            Console.WriteLine("42 squared = {0}", result);
        }
        public void EmitDynamicMethod_BindToClass()
        {
            // 创建动态方法
            // 如果方法的委托要绑定到对象, 第一个参数必须与委托要绑定到的类型匹配
            var methodArgs     = new[] { GetType(), typeof(int) };
            var multiplyHidden = new DynamicMethod(
                // 名称
                string.Empty,
                // 返回类型
                typeof(int),
                // 参数
                methodArgs,
                // 绑定到的类型
                GetType());

            // 发出动态方法
            ILGenerator iLGenerator = multiplyHidden.GetILGenerator();

            // 将类型参数放到堆栈
            iLGenerator.Emit(OpCodes.Ldarg_0);
            var testInfo = GetType().GetField("test", BindingFlags.NonPublic | BindingFlags.Instance);

            // 寻找当前求值堆栈上引用的对象的一个字段值
            iLGenerator.Emit(OpCodes.Ldfld, testInfo);
            // 将第二个参数加载到堆栈上
            iLGenerator.Emit(OpCodes.Ldarg_1);
            // 将俩个值相乘
            iLGenerator.Emit(OpCodes.Mul);
            // 将结果返回
            iLGenerator.Emit(OpCodes.Ret);
            // 创建委托
            OneParameter <int, int> invoker =
                (OneParameter <int, int>)
                multiplyHidden.CreateDelegate(
                    typeof(OneParameter <int, int>),
                    Activator.CreateInstance(GetType()));
            var actual = invoker(3);

            Assert.Equal(3 * 42, actual);
        }
Example #5
0
        public MysqlFastLoader(MySqlDataReader reader)
        {
            if (reader.Read())
            {
                Type[] types = { typeof(IDataReader) };
                // what we need to do is create a customer reader for this column...
                method = new DynamicMethod(string.Empty, typeof(void), types);

                ILGenerator il = method.GetILGenerator();

                Label lb = il.DefineLabel();

                il.MarkLabel(lb);

                for (int i = 0; i < reader.FieldCount; i++)
                {
                    Label dyn = il.DefineLabel();

                    var typeCode = Type.GetTypeCode(reader.GetFieldType(i));

                    il.Emit(OpCodes.Ldc_I4, i);
                    il.Emit(OpCodes.Ldarg_0);

                    il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                            GetMethod(nameof(IDataReader.IsDBNull), new Type[] { typeof(int) }));
                    il.Emit(OpCodes.Brtrue, dyn);

                    il.Emit(OpCodes.Ldc_I4, i);
                    il.Emit(OpCodes.Ldarg_0);

                    switch (typeCode)
                    {
                    case TypeCode.Boolean:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetBoolean), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.Char:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetChar), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.SByte:
                    case TypeCode.Byte:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetByte), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.Int16:
                    case TypeCode.UInt16:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetInt16), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.Int32:
                    case TypeCode.UInt32:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetInt32), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.Int64:
                    case TypeCode.UInt64:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetInt64), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.Single:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetFloat), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.Double:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetDouble), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.Decimal:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetDecimal), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.DateTime:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetDateTime), new Type[] { typeof(int) }));

                        il.Emit(OpCodes.Call, typeof(Convert).
                                GetMethod(nameof(Convert.ToString)));
                        break;

                    case TypeCode.String:
                        il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                                GetMethod(nameof(IDataReader.GetString)));
                        break;

                    default:
                        break;
                    }

                    il.Emit(OpCodes.Call, typeof(Console).
                            GetMethod(nameof(Console.Write), new Type[] { typeof(string) }));

                    il.MarkLabel(dyn);
                }

                il.Emit(OpCodes.Call, typeof(Console).
                        GetMethod(nameof(Console.WriteLine), new Type[] { typeof(void) }));

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Callvirt, typeof(IDataReader).
                        GetMethod(nameof(IDataReader.Read)));
                il.Emit(OpCodes.Brtrue, lb);

                il.Emit(OpCodes.Ret);

                OneParameter <IDataReader> invokeSquareIt =
                    (OneParameter <IDataReader>)
                    method.CreateDelegate(typeof(OneParameter <IDataReader>));

                invokeSquareIt(reader);
            }
            //var columnName = reader.GetName(i);
            //var value = reader[i];
            //var dotNetType = reader.GetFieldType(i);
            //var sqlType = reader.GetDataTypeName(i);
            //var specificType = reader.GetProviderSpecificFieldType(i);
            //fieldMetaData.columnName = columnName;
            //fieldMetaData.value = value;
            //fieldMetaData.dotNetType = dotNetType;
            //fieldMetaData.sqlType = sqlType;
            //fieldMetaData.specificType = specificType;
            //metaDataList.Add(fieldMetaData);
        }
Example #6
0
    //</Snippet12>
    //</Snippet2>

    public static void Main()
    {
        // Example 1: A simple dynamic method.
        //
        // Create an array that specifies the parameter types for the
        // dynamic method. In this example the only parameter is an
        // int, so the array has only one element.
        //
        //<Snippet3>
        Type[] methodArgs = { typeof(int) };
        //</Snippet3>

        // Create a DynamicMethod. In this example the method is
        // named SquareIt. It is not necessary to give dynamic
        // methods names. They cannot be invoked by name, and two
        // dynamic methods can have the same name. However, the
        // name appears in calls stacks and can be useful for
        // debugging.
        //
        // In this example the return type of the dynamic method
        // is long. The method is associated with the module that
        // contains the Example class. Any loaded module could be
        // specified. The dynamic method is like a module-level
        // static method.
        //
        //<Snippet4>
        DynamicMethod squareIt = new DynamicMethod(
            "SquareIt",
            typeof(long),
            methodArgs,
            typeof(Example).Module);
        //</Snippet4>

        // Emit the method body. In this example ILGenerator is used
        // to emit the MSIL. DynamicMethod has an associated type
        // DynamicILInfo that can be used in conjunction with
        // unmanaged code generators.
        //
        // The MSIL loads the argument, which is an int, onto the
        // stack, converts the int to a long, duplicates the top
        // item on the stack, and multiplies the top two items on the
        // stack. This leaves the squared number on the stack, and
        // all the method has to do is return.
        //
        //<Snippet5>
        ILGenerator il = squareIt.GetILGenerator();

        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Conv_I8);
        il.Emit(OpCodes.Dup);
        il.Emit(OpCodes.Mul);
        il.Emit(OpCodes.Ret);
        //</Snippet5>

        // Create a delegate that represents the dynamic method.
        // Creating the delegate completes the method, and any further
        // attempts to change the method (for example, by adding more
        // MSIL) are ignored. The following code uses a generic
        // delegate that can produce delegate types matching any
        // single-parameter method that has a return type.
        //
        //<Snippet6>
        OneParameter <long, int> invokeSquareIt =
            (OneParameter <long, int>)
            squareIt.CreateDelegate(typeof(OneParameter <long, int>));

        Console.WriteLine("123456789 squared = {0}",
                          invokeSquareIt(123456789));
        //</Snippet6>

        // Example 2: A dynamic method bound to an instance.
        //
        // Create an array that specifies the parameter types for a
        // dynamic method. If the delegate representing the method
        // is to be bound to an object, the first parameter must
        // match the type the delegate is bound to. In the following
        // code the bound instance is of the Example class.
        //
        //<Snippet13>
        Type[] methodArgs2 = { typeof(Example), typeof(int) };
        //</Snippet13>

        // Create a DynamicMethod. In this example the method has no
        // name. The return type of the method is int. The method
        // has access to the protected and private data of the
        // Example class.
        //
        //<Snippet14>
        DynamicMethod multiplyHidden = new DynamicMethod(
            "",
            typeof(int),
            methodArgs2,
            typeof(Example));
        //</Snippet14>

        // Emit the method body. In this example ILGenerator is used
        // to emit the MSIL. DynamicMethod has an associated type
        // DynamicILInfo that can be used in conjunction with
        // unmanaged code generators.
        //
        // The MSIL loads the first argument, which is an instance of
        // the Example class, and uses it to load the value of a
        // private instance field of type int. The second argument is
        // loaded, and the two numbers are multiplied. If the result
        // is larger than int, the value is truncated and the most
        // significant bits are discarded. The method returns, with
        // the return value on the stack.
        //
        //<Snippet15>
        ILGenerator ilMH = multiplyHidden.GetILGenerator();

        ilMH.Emit(OpCodes.Ldarg_0);

        FieldInfo testInfo = typeof(Example).GetField("test",
                                                      BindingFlags.NonPublic | BindingFlags.Instance);

        ilMH.Emit(OpCodes.Ldfld, testInfo);
        ilMH.Emit(OpCodes.Ldarg_1);
        ilMH.Emit(OpCodes.Mul);
        ilMH.Emit(OpCodes.Ret);
        //</Snippet15>

        // Create a delegate that represents the dynamic method.
        // Creating the delegate completes the method, and any further
        // attempts to change the method — for example, by adding more
        // MSIL — are ignored.
        //
        // The following code binds the method to a new instance
        // of the Example class whose private test field is set to 42.
        // That is, each time the delegate is invoked the instance of
        // Example is passed to the first parameter of the method.
        //
        // The delegate OneParameter is used, because the first
        // parameter of the method receives the instance of Example.
        // When the delegate is invoked, only the second parameter is
        // required.
        //
        //<Snippet16>
        OneParameter <int, int> invoke = (OneParameter <int, int>)
                                         multiplyHidden.CreateDelegate(
            typeof(OneParameter <int, int>),
            new Example(42)
            );

        Console.WriteLine("3 * test = {0}", invoke(3));
        //</Snippet16>
    }
Example #7
0
        public static void Test()
        {
            // Example 1: A simple dynamic method.
            //
            // Create an array that specifies the parameter types for the
            // dynamic method. In this example the only parameter is an
            // int, so the array has only one element.
            //
            Type[] methodArgs = { typeof(int) };

            // Create a DynamicMethod. In this example the method is
            // named SquareIt. It is not necessary to give dynamic
            // methods names. They cannot be invoked by name, and two
            // dynamic methods can have the same name. However, the
            // name appears in calls stacks and can be useful for
            // debugging.
            //
            // In this example the return type of the dynamic method
            // is long. The method is associated with the module that
            // contains the Example class. Any loaded module could be
            // specified. The dynamic method is like a module-level
            // static method.
            //
            DynamicMethod squareIt = new DynamicMethod(
                "SquareIt",
                typeof(long),
                methodArgs,
                typeof(EmitTest).Module);


            // Emit the method body. In this example ILGenerator is used
            // to emit the MSIL. DynamicMethod has an associated type
            // DynamicILInfo that can be used in conjunction with
            // unmanaged code generators.
            //
            // The MSIL loads the argument, which is an int, onto the
            // stack, converts the int to a long, duplicates the top
            // item on the stack, and multiplies the top two items on the
            // stack. This leaves the squared number on the stack, and
            // all the method has to do is return.
            //
            ILGenerator il = squareIt.GetILGenerator();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Conv_I8);
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Mul);
            il.Emit(OpCodes.Ret);

            // Create a delegate that represents the dynamic method.
            // Creating the delegate completes the method, and any further
            // attempts to change the method (for example, by adding more
            // MSIL) are ignored. The following code uses a generic
            // delegate that can produce delegate types matching any
            // single-parameter method that has a return type.
            //
            OneParameter <long, int> invokeSquareIt =
                (OneParameter <long, int>)
                squareIt.CreateDelegate(typeof(OneParameter <long, int>));

            Console.WriteLine("2 squared = {0}",
                              invokeSquareIt(2));
        }