예제 #1
0
        /// <summary>
        /// Implements a method on the mocked object. The method will simply call down to the
        /// </summary>
        /// <param name="methodToImplement">The method to implement.</param>
        private void ImplementMethod(MethodInfo methodToImplement)
        {
            IEnumerable <Type> parameterTypes = methodToImplement.GetParameters().Select(p => p.ParameterType);
            MethodBuilder      methodBuilder  = _typeBuilder.DefineMethod(methodToImplement.Name, MethodAttributes.Public | MethodAttributes.Virtual, methodToImplement.ReturnType, parameterTypes.ToArray());

            methodBuilder.CreateMethodBody(null, 0);
            ILGenerator  methodILGenerator      = methodBuilder.GetILGenerator();
            LocalBuilder resultLocalBuilder     = methodILGenerator.DeclareLocal(methodToImplement.ReturnType);
            LocalBuilder parametersLocalBuilder = methodILGenerator.DeclareLocal(typeof(object[]));

            methodILGenerator.Emit(OpCodes.Ldarg_0);
            methodILGenerator.Emit(OpCodes.Ldfld, __recorder0);
            methodILGenerator.Emit(OpCodes.Call, GetMethodBaseGetCurrentMethod());
            methodILGenerator.Emit(OpCodes.Ldc_I4_1);
            methodILGenerator.Emit(OpCodes.Newarr, typeof(object));
            methodILGenerator.Emit(OpCodes.Stloc_1);
            methodILGenerator.Emit(OpCodes.Ldloc_1);
            for (int parameterIndex = 0; parameterIndex < methodToImplement.GetParameters().Length; parameterIndex++)
            {
                methodILGenerator.Emit(OpCodes.Ldc_I4, parameterIndex);
                methodILGenerator.Emit(OpCodes.Ldarg, parameterIndex + 1);
                methodILGenerator.Emit(OpCodes.Stelem_Ref);
            }
            methodILGenerator.Emit(OpCodes.Ldloc_1);
            methodILGenerator.Emit(OpCodes.Callvirt, GetIMockRecorderMethodCallFor(methodToImplement.ReturnType));
            methodILGenerator.Emit(OpCodes.Stloc_0);
            methodILGenerator.Emit(OpCodes.Ldloc_0);
            methodILGenerator.Emit(OpCodes.Ret);
            _typeBuilder.DefineMethodOverride(methodBuilder, methodToImplement);
        }
예제 #2
0
        public void TestCreateMethodBody()
        {
            MethodBuilder mb = genClass.DefineMethod(
                genMethodName(), 0, typeof(void), new Type [0]);

            // Clear body
            mb.CreateMethodBody(null, 999);

            // Check arguments 1.
            try {
                mb.CreateMethodBody(new byte [1], -1);
                Assert.Fail("#1");
            } catch (ArgumentOutOfRangeException) {
            }

            // Check arguments 2.
            try {
                mb.CreateMethodBody(new byte [1], 2);
                Assert.Fail("#2");
            } catch (ArgumentOutOfRangeException) {
            }

            mb.CreateMethodBody(new byte [2], 1);

            // Could only be called once
            try {
                mb.CreateMethodBody(new byte [2], 1);
                Assert.Fail("#3");
            } catch (InvalidOperationException) {
            }

            // Can not be called on a created type
            TypeBuilder   tb  = module.DefineType(genTypeName(), TypeAttributes.Public);
            MethodBuilder mb2 = tb.DefineMethod(
                genMethodName(), 0, typeof(void), new Type [0]);
            ILGenerator ilgen = mb2.GetILGenerator();

            ilgen.Emit(OpCodes.Ret);
            tb.CreateType();

            try {
                mb2.CreateMethodBody(new byte [2], 1);
                Assert.Fail("#4");
            } catch (InvalidOperationException) {
            }
        }
예제 #3
0
        public void ZeroLengthBodyTest2()
        {
            MethodBuilder mb = genClass.DefineMethod(
                genMethodName(), 0, typeof(void),
                new Type [2] {
                typeof(int), typeof(int)
            });

            mb.CreateMethodBody(new byte [2], 0);
        }
예제 #4
0
        public void TestMethodHandleComplete()
        {
            MethodBuilder mb = genClass.DefineMethod(
                genMethodName(), 0, typeof(void), new Type [0]);

            mb.CreateMethodBody(new byte [2], 1);
            genClass.CreateType();

            RuntimeMethodHandle handle = mb.MethodHandle;
        }
예제 #5
0
        public void TestDefineParameterValidIndexComplete()
        {
            TypeBuilder   tb = module.DefineType(genTypeName(), TypeAttributes.Public);
            MethodBuilder mb = tb.DefineMethod(genMethodName(), 0, typeof(void),
                                               new Type [2] {
                typeof(int), typeof(int)
            });

            mb.CreateMethodBody(new byte [2], 1);
            tb.CreateType();
            mb.DefineParameter(1, ParameterAttributes.None, "param1");
        }
예제 #6
0
// This class will demonstrate how to create a method body using
// the MethodBuilder.CreateMethodBody(byte[], int) method.

    public static Type BuildDynType()
    {
        Type addType = null;

        AppDomain currentDom = Thread.GetDomain();

        AssemblyName myAsmName = new AssemblyName();

        myAsmName.Name = "MyDynamicAssembly";

        AssemblyBuilder myAsmBldr = currentDom.DefineDynamicAssembly(
            myAsmName,
            AssemblyBuilderAccess.RunAndSave);

        // The dynamic assembly space has been created.  Next, create a module
        // within it.  The type Point will be reflected into this module.

        ModuleBuilder myModuleBldr = myAsmBldr.DefineDynamicModule("MyModule");

        TypeBuilder myTypeBldr = myModuleBldr.DefineType("Adder");

        MethodBuilder myMthdBldr = myTypeBldr.DefineMethod("DoAdd",
                                                           MethodAttributes.Public |
                                                           MethodAttributes.Static,
                                                           typeof(int),
                                                           new Type[]
                                                           { typeof(int), typeof(int) });

        // Build the array of Bytes holding the MSIL instructions.

        byte[] ILcodes = new byte[] {
            0x02, /* 02h is the opcode for ldarg.0 */
            0x03, /* 03h is the opcode for ldarg.1 */
            0x58, /* 58h is the opcode for add     */
            0x2A  /* 2Ah is the opcode for ret     */
        };

        myMthdBldr.CreateMethodBody(ILcodes, ILcodes.Length);

        addType = myTypeBldr.CreateType();

        return(addType);
    }
예제 #7
0
        public void TestDefineParameter()
        {
            TypeBuilder   tb = module.DefineType(genTypeName(), TypeAttributes.Public);
            MethodBuilder mb = tb.DefineMethod(
                genMethodName(), 0, typeof(void),
                new Type [2] {
                typeof(int), typeof(int)
            });

            // index out of range

            // This fails on mono because the mono version accepts a 0 index

            /*
             * try {
             *      mb.DefineParameter (0, 0, "param1");
             *      Fail ();
             * } catch (ArgumentOutOfRangeException) {
             * }
             */

            try {
                mb.DefineParameter(3, 0, "param1");
                Assert.Fail("#1");
            } catch (ArgumentOutOfRangeException) {
            }

            // Normal usage
            mb.DefineParameter(1, 0, "param1");
            mb.DefineParameter(1, 0, "param1");
            mb.DefineParameter(2, 0, null);

            mb.CreateMethodBody(new byte [2], 1);
            tb.CreateType();
            try {
                mb.DefineParameter(1, 0, "param1");
                Assert.Fail("#2");
            } catch (InvalidOperationException) {
            }
        }
예제 #8
0
        public void TestMethodImplementationFlags()
        {
            TypeBuilder   tb = module.DefineType(genTypeName(), TypeAttributes.Public);
            MethodBuilder mb = tb.DefineMethod(
                genMethodName(), 0, typeof(void), new Type [0]);

            Assert.AreEqual(MethodImplAttributes.Managed | MethodImplAttributes.IL,
                            mb.GetMethodImplementationFlags(), "#1");

            mb.SetImplementationFlags(MethodImplAttributes.OPTIL);

            Assert.AreEqual(MethodImplAttributes.OPTIL, mb.GetMethodImplementationFlags(), "#2");

            mb.CreateMethodBody(new byte [2], 1);
            mb.SetImplementationFlags(MethodImplAttributes.Managed);
            tb.CreateType();
            try {
                mb.SetImplementationFlags(MethodImplAttributes.OPTIL);
                Assert.Fail("#3");
            } catch (InvalidOperationException) {
            }
        }
        private static void CreateMembers(TypeBuilder typeBuilder, string propertyName, Type propertyType)
        {
            MethodInfo methodInfo = typeof(Dummy).GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic);
            MethodBody methodBody = methodInfo.GetMethodBody();
            //Debug.LogFormat("Method: {0}", methodBody.MaxStackSize);
            var bytes = methodBody.GetILAsByteArray();

            MethodBuilder methodBuilder = typeBuilder.DefineMethod("Update", MethodAttributes.Private);

            methodBuilder.CreateMethodBody(bytes, bytes.Length);

            //ILGenerator methIL = methodBuilder.GetILGenerator();
            //// To retrieve the private instance field, load the instance it
            //// belongs to (argument zero). After loading the field, load the
            //// argument one and then multiply. Return from the method with
            //// the return value (the product of the two numbers) on the
            //// execution stack.
            //methIL.Emit(OpCodes.Ldarg_0);
            //methIL.Emit(OpCodes.Nop);
            //methIL.Emit(OpCodes.Nop);
            //methIL.Emit(OpCodes.Ret);
        }
예제 #10
0
        /// <summary>
        /// Generates the method implementation.
        /// </summary>
        /// <param name="typeBuilder">The type builder.</param>
        /// <param name="currentType">Type of the current.</param>
        protected virtual void GenerateMethodImpl(TypeBuilder typeBuilder, Type currentType)
        {
            MethodInfo[] methods = currentType.GetMethods();

            foreach (MethodInfo method in methods)
            {
                Type[]        parameterTypes = GetParameterTypeList(method.GetParameters());
                MethodBuilder methodBuilder  = typeBuilder.DefineMethod(method.Name, DefaultMethodAttributes, method.ReturnType, parameterTypes);

                methodBuilder.CreateMethodBody(null, 0);
                ILGenerator ilGenerator = methodBuilder.GetILGenerator();

                this.GenerateMethodImpl(method, parameterTypes, ilGenerator);

                typeBuilder.DefineMethodOverride(methodBuilder, method);
            }

            Type[] inheritedInterfaces = currentType.GetInterfaces();

            foreach (Type inheritedInterface in inheritedInterfaces)
            {
                this.GenerateMethodImpl(typeBuilder, inheritedInterface);
            }
        }
예제 #11
0
        protected virtual void GenerateMethodImpl(TypeBuilder builder, Type currentType)
        {
            MethodInfo[] methods = currentType.GetMethods();
            foreach (MethodInfo method in methods)
            {
                Type[]        parameterTypes = GetParameters(method.GetParameters());          // declare the method with the correct parameters
                MethodBuilder methodBuilder  = builder.DefineMethod(method.Name, defaultMethodAttributes, method.ReturnType, parameterTypes);

                // Start building the method
                methodBuilder.CreateMethodBody(null, 0);
                ILGenerator iLGenerator = methodBuilder.GetILGenerator();

                GenerateMethodImpl(method, parameterTypes, iLGenerator);

                // declare that we override the interface method
                builder.DefineMethodOverride(methodBuilder, method);
            }

            Type[] inheritedInterfaces = currentType.GetInterfaces();
            foreach (Type inheritedInterface in inheritedInterfaces)
            {
                GenerateMethodImpl(builder, inheritedInterface);
            }
        }
예제 #12
0
 protected override void SetIL(MethodBuilder methodBuilder, MemoryStream ilStream)
 {
     methodBuilder.CreateMethodBody(ilStream.ToArray(), (int)ilStream.Length);
 }
예제 #13
0
        public static Delegate CreateDelegate(SharedDelegate sharedDel)
        {
            lock (IncrementalName)
            {
                int SharedId = sharedDel.sharedMethod.sharedClass.SharedId;

                if (!cache.ContainsKey(SharedId))
                {
                    cache.Add(SharedId, new SortedList <int, Delegate>());
                }
                if (cache[SharedId].ContainsKey(sharedDel.sharedMethod.DelegateId))
                {
                    return(cache[SharedId][sharedDel.sharedMethod.DelegateId]);
                }

                TypeBuilder typeBuilder = modBuilder.DefineType("_Del" + IncrementName(), TypeAttributes.Public |
                                                                TypeAttributes.Class |
                                                                TypeAttributes.AutoClass |
                                                                TypeAttributes.AnsiClass |
                                                                TypeAttributes.BeforeFieldInit |
                                                                TypeAttributes.AutoLayout |
                                                                TypeAttributes.Sealed,
                                                                typeof(object));

                FieldBuilder       fb          = typeBuilder.DefineField("$haredDelegate", typeof(SharedDelegate), FieldAttributes.Private);
                ConstructorBuilder constructor = typeBuilder.DefineConstructor(MethodAttributes.Public |
                                                                               MethodAttributes.SpecialName |
                                                                               MethodAttributes.RTSpecialName,
                                                                               CallingConventions.Standard,
                                                                               new Type[] { typeof(SharedDelegate) });

                ConstructorInfo conObj = typeof(object).GetConstructor(new Type[0]);
                ILGenerator     il     = constructor.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Call, conObj);

                //set sharedClass variable
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Stfld, fb);
                il.Emit(OpCodes.Ret);

                string        MethodName = IncrementName();
                MethodBuilder builder    = typeBuilder.DefineMethod(MethodName, MethodAttributes.Public, CallingConventions.HasThis, sharedDel.sharedMethod.ReturnType, sharedDel.sharedMethod.ArgumentTypes);

                builder.CreateMethodBody(null, 0);
                ILGenerator gen = builder.GetILGenerator();

                MethodInfo   SharedCall = typeof(SharedDelegate).GetMethod("Invoke");
                LocalBuilder lb         = gen.DeclareLocal(typeof(object[]));

                //init local array
                gen.Emit(OpCodes.Ldc_I4, sharedDel.sharedMethod.ArgumentTypes.Length);
                gen.Emit(OpCodes.Newarr, typeof(object));
                gen.Emit(OpCodes.Stloc_0);

                for (int i = 0; i < sharedDel.sharedMethod.ArgumentTypes.Length; i++)
                {
                    gen.Emit(OpCodes.Ldloc_0);
                    gen.Emit(OpCodes.Ldc_I4, i);
                    gen.Emit(OpCodes.Ldarg, i + 1);

                    if (sharedDel.sharedMethod.ArgumentTypes[i].IsByRef)
                    {
                        //remove & at the end since ref/out adds & at the end of the argument
                        sharedDel.sharedMethod.ArgumentTypes[i] = Type.GetType(sharedDel.sharedMethod.ArgumentTypes[i].FullName.Substring(0, sharedDel.sharedMethod.ArgumentTypes[i].FullName.Length - 1));
                    }

                    gen.Emit(OpCodes.Box, sharedDel.sharedMethod.ArgumentTypes[i]);
                    gen.Emit(OpCodes.Stelem_Ref);
                }


                //load $haredDelegate
                gen.Emit(OpCodes.Ldarg_0);
                gen.Emit(OpCodes.Ldfld, fb);

                gen.Emit(OpCodes.Ldloc_0);
                gen.Emit(OpCodes.Callvirt, SharedCall);

                bool isInt = sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Int32)) ||
                             sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.UInt32)) ||
                             sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Boolean)) ||
                             sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.Int64)) ||
                             sharedDel.sharedMethod.ReturnType.IsAssignableFrom(typeof(System.UInt64));

                if (sharedDel.sharedMethod.ReturnType.FullName != "System.Void" && !isInt)
                {
                    gen.Emit(OpCodes.Box, sharedDel.sharedMethod.ReturnType);
                }
                else if (sharedDel.sharedMethod.ReturnType.FullName == "System.Void") //no return
                {
                    gen.Emit(OpCodes.Pop);
                }
                else if (isInt)
                {
                    gen.Emit(OpCodes.Unbox, sharedDel.sharedMethod.ReturnType);
                    gen.Emit(OpCodes.Ldobj, sharedDel.sharedMethod.ReturnType);
                }
                gen.Emit(OpCodes.Ret);

                Type   InitType   = typeBuilder.CreateType();
                object InitObject = InitType.GetConstructor(new Type[] { typeof(SharedDelegate) }).Invoke(new object[] { sharedDel });

                MethodInfo info = InitObject.GetType().GetMethod(MethodName);
                return(Delegate.CreateDelegate(sharedDel.DelegateType, InitObject, info));
            }
        }