/// <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); }
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) { } }
public void ZeroLengthBodyTest2() { MethodBuilder mb = genClass.DefineMethod( genMethodName(), 0, typeof(void), new Type [2] { typeof(int), typeof(int) }); mb.CreateMethodBody(new byte [2], 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; }
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"); }
// 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); }
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) { } }
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); }
/// <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); } }
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); } }
protected override void SetIL(MethodBuilder methodBuilder, MemoryStream ilStream) { methodBuilder.CreateMethodBody(ilStream.ToArray(), (int)ilStream.Length); }
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)); } }