System.Reflection.Emit.DynamicMethod.GetILGenerator()

Here are the examples of the csharp api System.Reflection.Emit.DynamicMethod.GetILGenerator() taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

538 Examples 7

19 Source : Mem.cs
with GNU General Public License v3.0
from Decimation

private static Action<object, Action<object>> CreatePinImpl()
		{
			var method = new DynamicMethod("InvokeWhilePinnedImpl", typeof(void),
			                               new[] { typeof(object), typeof(Action<object>) },
			                               typeof(RuntimeProperties).Module);

			ILGenerator il = method.GetILGenerator();

			// create a pinned local variable of type object
			// this wouldn't be valid in C#, but the runtime doesn't complain about the IL
			LocalBuilder local = il.DeclareLocal(typeof(object), true);

			// store first argument obj in the pinned local variable
			il.Emit(OpCodes.Ldarg_0);
			il.Emit(OpCodes.Stloc_0);
			// invoke the delegate
			il.Emit(OpCodes.Ldarg_1);
			il.Emit(OpCodes.Ldarg_0);
			il.EmitCall(OpCodes.Callvirt, typeof(Action<object>).GetMethod("Invoke")!, null);

			il.Emit(OpCodes.Ret);

			return (Action<object, Action<object>>) method.CreateDelegate(typeof(Action<object, Action<object>>));
		}

19 Source : Helpers.cs
with BSD 3-Clause "New" or "Revised" License
from developervariety

public static Delegate CreateDeserializeDelegate(Type paramType, TypeData data)
		{
			Type readerType = data.Type;

			if (paramType != readerType && paramType != typeof(object))
				throw new Exception();

			bool needTypeConv = paramType != readerType;
			bool needsInstanceParameter = data.ReaderNeedsInstance;

			var delegateType = typeof(DeserializeDelegate<>).MakeGenericType(paramType);

			// Can we call the reader directly?

			if (!needTypeConv && needsInstanceParameter)
			{
				var dynamicReader = data.ReaderMethodInfo as DynamicMethod;

				if (dynamicReader != null)
					return dynamicReader.CreateDelegate(delegateType);
				else
					return Delegate.CreateDelegate(delegateType, data.ReaderMethodInfo);
			}

			// Create a trampoline

			var wrapper = GenerateDynamicDeserializerStub(paramType);
			var il = wrapper.GetILGenerator();

			if (needsInstanceParameter)
				il.Emit(OpCodes.Ldarg_0);

			if (needTypeConv && readerType.IsValueType)
			{
				var local = il.DeclareLocal(readerType);

				il.Emit(OpCodes.Ldarg_1);
				il.Emit(OpCodes.Ldloca_S, local);

				il.Emit(OpCodes.Call, data.ReaderMethodInfo);

				// write result object to out object
				il.Emit(OpCodes.Ldarg_2);
				il.Emit(OpCodes.Ldloc_0);
				il.Emit(OpCodes.Box, readerType);
				il.Emit(OpCodes.Stind_Ref);
			}
			else
			{
				il.Emit(OpCodes.Ldarg_1);
				il.Emit(OpCodes.Ldarg_2);

				// XXX tailcall causes slowdowns with large valuetypes
				//il.Emit(OpCodes.Tailcall);
				il.Emit(OpCodes.Call, data.ReaderMethodInfo);
			}

			il.Emit(OpCodes.Ret);

			return wrapper.CreateDelegate(delegateType);
		}

19 Source : Helpers.cs
with BSD 3-Clause "New" or "Revised" License
from developervariety

public static Delegate CreateSerializeDelegate(Type paramType, TypeData data)
		{
			Type writerType = data.Type;

			if (paramType != writerType && paramType != typeof(object))
				throw new Exception();

			bool needTypeConv = paramType != writerType;
			bool needsInstanceParameter = data.WriterNeedsInstance;

			var delegateType = typeof(SerializeDelegate<>).MakeGenericType(paramType);

			// Can we call the writer directly?

			if (!needTypeConv && needsInstanceParameter)
			{
				var dynamicWriter = data.WriterMethodInfo as DynamicMethod;

				if (dynamicWriter != null)
					return dynamicWriter.CreateDelegate(delegateType);
				else
					return Delegate.CreateDelegate(delegateType, data.WriterMethodInfo);
			}

			// Create a trampoline

			var wrapper = Helpers.GenerateDynamicSerializerStub(paramType);
			var il = wrapper.GetILGenerator();

			if (needsInstanceParameter)
				il.Emit(OpCodes.Ldarg_0);

			il.Emit(OpCodes.Ldarg_1);
			il.Emit(OpCodes.Ldarg_2);
			if (needTypeConv)
				il.Emit(writerType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclreplaced, writerType);

			// XXX tailcall causes slowdowns with large valuetypes
			//il.Emit(OpCodes.Tailcall);
			il.Emit(OpCodes.Call, data.WriterMethodInfo);

			il.Emit(OpCodes.Ret);

			return wrapper.CreateDelegate(delegateType);
		}

19 Source : Serializer.cs
with BSD 3-Clause "New" or "Revised" License
from developervariety

void GenerateWriterBody(Type type)
		{
			replacedertLocked();

			var data = m_runtimeTypeMap[type];

			ITypeSerializer serializer = data.TypeSerializer;

			var writer = data.WriterMethodInfo as DynamicMethod;
			if (writer == null)
				return;

			var dynSer = (IDynamicTypeSerializer)serializer;

			dynSer.GenerateWriterMethod(this, type, writer.GetILGenerator());
		}

19 Source : Serializer.cs
with BSD 3-Clause "New" or "Revised" License
from developervariety

void GenerateReaderBody(Type type)
		{
			replacedertLocked();

			var data = m_runtimeTypeMap[type];

			ITypeSerializer serializer = data.TypeSerializer;

			var reader = data.ReaderMethodInfo as DynamicMethod;
			if (reader == null)
				return;

			var dynSer = (IDynamicTypeSerializer)serializer;

			dynSer.GenerateReaderMethod(this, type, reader.GetILGenerator());
		}

19 Source : MethodHelper.cs
with MIT License
from Dogwei

private static Delegate CreateDelegateByProxy(Type delegateType, MethodBase methodInfo)
        {
            if (methodInfo == null)
            {
                throw new ArgumentNullException(nameof(methodInfo));
            }

            Type[] parameterTypes;
            Type resultType;

            if (delegateType == null)
            {
                GetParametersTypes(methodInfo, out parameterTypes, out resultType);

                delegateType = GetOrDefineDelegateType(parameterTypes, resultType, true);
            }
            else
            {
                GetParametersTypes(delegateType, out parameterTypes, out resultType);
            }

            var dynamicMethod = new DynamicMethod(
                nameof(MethodHelper) + "_" + Guid.NewGuid().ToString("N"),
                resultType,
                parameterTypes,
                methodInfo.Module,
                true);

            var ilGen = dynamicMethod.GetILGenerator();

            for (int i = 0; i < parameterTypes.Length; ++i)
            {
                ilGen.LoadArgument(i);
            }

            ilGen.Call(methodInfo);

            ilGen.Emit(OpCodes.Ret);

            return dynamicMethod.CreateDelegate(delegateType);
        }

19 Source : TypeHelper.cs
with MIT License
from Dogwei

private static void GetAllFieldOffsetByDynamic(Type type)
        {
            if (intPtrChooseMinMethod == null)
            {
                lock (lockObject)
                {
                    if (intPtrChooseMinMethod == null)
                    {
                        intPtrChooseMinMethod = ((Func<IntPtr, IntPtr, IntPtr>)ChooseMin).Method;

                        idCacheUInt32AddMethod = typeof(IdCache<uint>).GetMethod(
                            nameof(IdCache<uint>.Add),
                            new Type[] { typeof(long), typeof(uint) });
                    }
                }
            }

            var dynamicMethod = new DynamicMethod(
                StringHelper.Format("{0}_{1}_{2}", nameof(OffsetOf), type.Name, Guid.NewGuid().ToString("N")),
                null, new Type[] { typeof(IdCache<uint>) },
                type.Module,
                true);

            var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);

            var ilGen = dynamicMethod.GetILGenerator();

            var instance = ilGen.DeclareLocal(typeof(IntPtr));
            var first = ilGen.DeclareLocal(typeof(IntPtr));

            /* 分配一个模拟实例 */
            ilGen.LoadConstant(8);
            ilGen.LocalAllocate();
            ilGen.StoreLocal(instance);

            /* 找到最小的静态字段地址 */
            var isFirstStatic = true;
            foreach (var item in fields)
            {
                /* 跳过常量 */
                if (item.IsLiteral)
                {
                    continue;
                }

                if (item.IsStatic)
                {
                    ilGen.LoadStaticFieldAddress(item);

                    if (isFirstStatic)
                    {
                        isFirstStatic = false;
                    }
                    else
                    {
                        ilGen.LoadLocal(first);
                        ilGen.Call(intPtrChooseMinMethod);
                    }

                    ilGen.StoreLocal(first);
                }
            }

            foreach (var item in fields)
            {
                /* 跳过常量 */
                if (item.IsLiteral)
                {
                    continue;
                }

                /* 加载 IdCache 实例 */
                ilGen.LoadArgument(0);
                /* 加载字段 Id */
                ilGen.LoadConstant((long)item.FieldHandle.Value);

                if (item.IsStatic)
                {
                    // Offset = Address - First Address.
                    ilGen.LoadStaticFieldAddress(item);
                    ilGen.LoadLocal(first);
                    ilGen.Subtract();
                }
                else
                {
                    /* Offset = Address - Instance. */
                    ilGen.LoadLocal(instance);
                    ilGen.LoadFieldAddress(item);
                    ilGen.LoadLocal(instance);
                    ilGen.Subtract();

                    /* if clreplaced then Offset -= sizeof TypeHandle. */
                    if (type.IsClreplaced)
                    {
                        ilGen.LoadConstant(IntPtr.Size);
                        ilGen.Subtract();
                    }
                }

                ilGen.ConvertInt32();
                ilGen.Call(idCacheUInt32AddMethod);
            }

            ilGen.Return();

            var action = (Action<IdCache<uint>>)dynamicMethod.CreateDelegate(typeof(Action<IdCache<uint>>));

            /* Call the DynamicMethod. */
            action(fieldOffsetCache);
        }

19 Source : TypeHelper.cs
with MIT License
from Dogwei

private static IntPtr GetTypeStaticMemoryAddressByDynamic(Type type)
        {
            var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);

            FieldInfo fieldInfo = null;

            foreach (var item in fields)
            {
                if (item.IsLiteral)
                {
                    continue;
                }

                fieldInfo = item;

                break;
            }

            if (fieldInfo == null)
            {
                return IntPtr.Zero;
            }

            var getFieldPointerMethod = new DynamicMethod(
                StringHelper.Format("{0}_{1}_{2}", nameof(GetTypeStaticMemoryAddressByDynamic), type.Name, Guid.NewGuid().ToString("N")),
                typeof(IntPtr),
                Type.EmptyTypes,
                fieldInfo.Module,
                true);

            var ilGen = getFieldPointerMethod.GetILGenerator();

            ilGen.Emit(OpCodes.Ldsflda, fieldInfo);
            ilGen.Emit(OpCodes.Ret);

            var pAddress = (IntPtr)getFieldPointerMethod.Invoke(null, null);

            var pResult = (IntPtr)((ulong)pAddress - OffsetOf(fieldInfo));

            return pResult;
        }

19 Source : MethodHelper.cs
with MIT License
from Dogwei

private static Delegate InternalCreateDelegateByProxy(Type delegateType, MethodInfo methodInfo)
        {
            GetParametersTypes(delegateType, out var parameterTypes, out var returnType);

            var dynamicMethod = new DynamicMethod(
                $"{nameof(MethodHelper)}_{Guid.NewGuid():N}",
                returnType,
                parameterTypes,
                methodInfo.Module,
                true);

            var ilGen = dynamicMethod.GetILGenerator();

            for (int i = 0; i < parameterTypes.Length; ++i)
            {
                ilGen.LoadArgument(i);
            }

            ilGen.Call(methodInfo);

            ilGen.Return();

            return dynamicMethod.CreateDelegate(delegateType);
        }

19 Source : DynamicAssembly.cs
with MIT License
from Dogwei

public static TDelegate BuildDynamicMethod<TDelegate>(Action<DynamicMethod, ILGenerator> callback, bool restrictedSkipVisibility = false) where TDelegate : Delegate
        {
            GetParametersTypes(typeof(TDelegate), out var parameterTypes, out var returnType);

            var dynamicMethod = new DynamicMethod(
                $"{nameof(Dynamicreplacedembly)}_{nameof(DynamicMethod)}_{Guid.NewGuid():N}",
                returnType,
                parameterTypes,
                restrictedSkipVisibility
                );

            callback(dynamicMethod, dynamicMethod.GetILGenerator());

            return CreateDelegate<TDelegate>(dynamicMethod);
        }

19 Source : DynamicAssembly.cs
with MIT License
from Dogwei

public static TDelegate BuildDynamicMethod<TDelegate>(Action<DynamicMethod, ILGenerator> callback, Module module, bool skipVisibility = false) where TDelegate : Delegate
        {
            GetParametersTypes(typeof(TDelegate), out var parameterTypes, out var returnType);

            var dynamicMethod = new DynamicMethod(
                $"{nameof(Dynamicreplacedembly)}_{nameof(DynamicMethod)}_{Guid.NewGuid():N}",
                returnType,
                parameterTypes,
                module,
                skipVisibility
                );

            callback(dynamicMethod, dynamicMethod.GetILGenerator());

            return CreateDelegate<TDelegate>(dynamicMethod);
        }

19 Source : Conversion.cs
with MIT License
from dotnet

public static Delegate ConvertDelegate(Type delegateType, Delegate inner)
        {
            // This code is based on:
            // http://blogs.msdn.com/joelpob/archive/2005/07/01/434728.aspx
            object target = inner;
            string methodName = "DynamicMethod"; //delegateType.ToString();
            MethodInfo signature = delegateType.GetMethod("Invoke");
            Type returnType = signature.ReturnType;
            Type innerReturnType = inner.Method.ReturnType;
            Conversion conv;
            if (!TryGetConversion(innerReturnType, returnType, out conv))
            {
                throw new ArgumentException("Return type of the innerMethod (" + innerReturnType.Name + ") cannot be converted to the delegate return type (" + returnType.Name +
                                            ")");
            }
            Converter c = conv.Converter;
            if (c != null)
            {
                target = new ConvertedDelegate(inner, c);
            }
            Type[] formals = Invoker.GetParameterTypes(signature);
            Type[] formalsWithTarget = formals;
            if (target != null)
            {
                formalsWithTarget = new Type[1 + formals.Length];
                formalsWithTarget[0] = target.GetType();
                formals.CopyTo(formalsWithTarget, 1);
            }
            DynamicMethod method = new DynamicMethod(methodName, returnType, formalsWithTarget, typeof (Conversion));
            ILGenerator il = method.GetILGenerator();
            // put the delegate parameters into an object[]
            LocalBuilder args = il.DeclareLocal(typeof (object[]));
            il.Emit(OpCodes.Ldc_I4, formals.Length);
            il.Emit(OpCodes.Newarr, typeof (object));
            il.Emit(OpCodes.Stloc, args);
            int offset = (target == null) ? 0 : 1;
            for (int i = 0; i < formals.Length; i++)
            {
                // args[i] = (arg i+1)
                il.Emit(OpCodes.Ldloc, args);
                il.Emit(OpCodes.Ldc_I4, i);
                il.Emit(OpCodes.Ldarg, i + offset);
                // box if necessary
                if (formals[i].IsValueType)
                {
                    il.Emit(OpCodes.Box, formals[i]);
                }
                il.Emit(OpCodes.Stelem_Ref);
            }
            // push the result converter on the stack
            if (c != null)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, typeof (ConvertedDelegate).GetField("Converter"));
            }
            // call the inner delegate
            il.Emit(OpCodes.Ldarg_0);
            if (c != null)
            {
                il.Emit(OpCodes.Ldfld, typeof (ConvertedDelegate).GetField("InnerDelegate"));
            }
            il.Emit(OpCodes.Ldloc, args);
            il.Emit(OpCodes.Call, inner.GetType().GetMethod("Invoke"));
            // handle the return value
            if (innerReturnType != typeof (void))
            {
                if (returnType == typeof (void))
                {
                    il.Emit(OpCodes.Pop);
                }
                else
                {
                    // converter object is already on the stack
                    // calling c.Method directly does not work (access exception)
                    //il.Emit(OpCodes.Call, c.Method);
                    il.Emit(OpCodes.Call, c.GetType().GetMethod("Invoke"));
                    // Converter always returns object, so unbox if necessary
                    if (returnType.IsValueType)
                    {
                        il.Emit(OpCodes.Unbox_Any, returnType);
                    }
                }
            }
            il.Emit(OpCodes.Ret);
            return method.CreateDelegate(delegateType, target);
        }

19 Source : ApiUtils.cs
with MIT License
from dotnet

private static Delegate GeneratePeek<TOwn, TRow, TValue>(FieldInfo fieldInfo, OpCode replacedignmentOpCode)
        {
            // REVIEW: It seems like we really should cache these, instead of generating them per cursor.
            Type[] args = { typeof(TOwn), typeof(TRow), typeof(long), typeof(TValue).MakeByRefType() };
            var mb = new DynamicMethod("Peek", null, args, typeof(TOwn), true);
            var il = mb.GetILGenerator();

            il.Emit(OpCodes.Ldarg_3);               // push arg3
            il.Emit(OpCodes.Ldarg_1);               // push arg1
            il.Emit(OpCodes.Ldfld, fieldInfo);      // push [stack top].[fieldInfo]
            // Stobj needs to coupled with a type.
            if (replacedignmentOpCode == OpCodes.Stobj)  // [stack top-1] = [stack top]
                il.Emit(replacedignmentOpCode, fieldInfo.FieldType);
            else
                il.Emit(replacedignmentOpCode);
            il.Emit(OpCodes.Ret);                   // ret

            return mb.CreateDelegate(typeof(Peek<TRow, TValue>));
        }

19 Source : ApiUtils.cs
with MIT License
from dotnet

private static Delegate GeneratePoke<TOwn, TRow, TValue>(FieldInfo fieldInfo, OpCode replacedignmentOpCode)
        {
            Type[] args = { typeof(TOwn), typeof(TRow), typeof(TValue) };
            var mb = new DynamicMethod("Poke", null, args, typeof(TOwn), true);
            var il = mb.GetILGenerator();

            il.Emit(OpCodes.Ldarg_1);               // push arg1
            il.Emit(OpCodes.Ldflda, fieldInfo);     // push addr([stack top].[fieldInfo])
            il.Emit(OpCodes.Ldarg_2);               // push arg2
            // Stobj needs to coupled with a type.
            if (replacedignmentOpCode == OpCodes.Stobj)  // [stack top-1] = [stack top]
                il.Emit(replacedignmentOpCode, fieldInfo.FieldType);
            else
                il.Emit(replacedignmentOpCode);
            il.Emit(OpCodes.Ret);                   // ret
            return mb.CreateDelegate(typeof(Poke<TRow, TValue>), null);
        }

19 Source : ApiUtils.cs
with MIT License
from dotnet

private static Delegate GeneratePoke<TOwn, TRow, TValue>(PropertyInfo propertyInfo)
        {
            Type[] args = { typeof(TOwn), typeof(TRow), typeof(TValue) };
            var mb = new DynamicMethod("Poke", null, args, typeof(TOwn), true);
            var il = mb.GetILGenerator();
            var minfo = propertyInfo.GetSetMethod();
            var opcode = (minfo.IsVirtual || minfo.IsAbstract) ? OpCodes.Callvirt : OpCodes.Call;

            il.Emit(OpCodes.Ldarg_1);               // push arg1
            il.Emit(OpCodes.Ldarg_2);               // push arg2
            il.Emit(opcode, minfo);                 // call [stack top-1].set_[propertyInfo]([stack top])
            il.Emit(OpCodes.Ret);                   // ret
            return mb.CreateDelegate(typeof(Poke<TRow, TValue>), null);
        }

19 Source : ApiUtils.cs
with MIT License
from dotnet

private static Delegate GeneratePeek<TOwn, TRow, TValue>(PropertyInfo propertyInfo, OpCode replacedignmentOpCode)
        {
            // REVIEW: It seems like we really should cache these, instead of generating them per cursor.
            Type[] args = { typeof(TOwn), typeof(TRow), typeof(long), typeof(TValue).MakeByRefType() };
            var mb = new DynamicMethod("Peek", null, args, typeof(TOwn), true);
            var il = mb.GetILGenerator();
            var minfo = propertyInfo.GetGetMethod();
            var opcode = (minfo.IsVirtual || minfo.IsAbstract) ? OpCodes.Callvirt : OpCodes.Call;

            il.Emit(OpCodes.Ldarg_3);               // push arg3
            il.Emit(OpCodes.Ldarg_1);               // push arg1
            il.Emit(opcode, minfo);                 // call [stack top].get_[propertyInfo]()
            // Stobj needs to coupled with a type.
            if (replacedignmentOpCode == OpCodes.Stobj)  // [stack top-1] = [stack top]
                il.Emit(replacedignmentOpCode, propertyInfo.PropertyType);
            else
                il.Emit(replacedignmentOpCode);
            il.Emit(OpCodes.Ret);                   // ret

            return mb.CreateDelegate(typeof(Peek<TRow, TValue>));
        }

19 Source : DynamicMethodRuntime.cs
with MIT License
from dotnet

private DelegateCreator CreateDelegateCreator(Type targetType)
        {
            const BindingFlags helperFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;

            // We are relying on WPF-generated delegate helper for now
            // Expected signature: internal Delegate _CreateDelegate(Type delegateType, string handler)
            // If it's not present, we just return a wrapper around Delegate.CreateDelegate, which
            // will fail if we the _localreplacedembly doesn't have RestrictedMemberAccess permission
            MethodInfo helper = targetType.GetMethod(KnownStrings.CreateDelegateHelper,
                helperFlags, null, new Type[] { typeof(Type), typeof(string) }, null);
            if (helper == null)
            {
                if (_delegateCreatorWithoutHelper == null)
                {
                    _delegateCreatorWithoutHelper = CreateDelegateCreatorWithoutHelper();
                }
                return _delegateCreatorWithoutHelper;
            }

            DynamicMethod dynamicMethod = CreateDynamicMethod(targetType.Name + "DelegateHelper",
                typeof(Delegate), typeof(Type), typeof(object), typeof(string));
            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

            // We have to emit an indirect call through reflection to avoid the helper getting
            // inlined into the dynamic method, and potentially executing without access to private
            // members on the target type.
            Emit_LateBoundInvoke(ilGenerator, targetType, KnownStrings.CreateDelegateHelper, 
                helperFlags | BindingFlags.InvokeMethod, 1, 0, 2);
            Emit_CastTo(ilGenerator, typeof(Delegate));
            ilGenerator.Emit(OpCodes.Ret);

            return (DelegateCreator)dynamicMethod.CreateDelegate(typeof(DelegateCreator));
        }

19 Source : DynamicMethodRuntime.cs
with MIT License
from dotnet

private PropertySetDelegate CreateSetDelegate(MethodInfo setter)
        {
            DynamicMethod dynamicMethod = CreateDynamicMethod(setter.Name + "Setter", 
                typeof(void), typeof(object), typeof(object));
            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

            ParameterInfo[] parameters = setter.GetParameters();
            Type targetType = setter.IsStatic ? parameters[0].ParameterType : GetTargetType(setter);
            Type valueType = setter.IsStatic ? parameters[1].ParameterType : parameters[0].ParameterType;

            ilGenerator.Emit(OpCodes.Ldarg_0);
            Emit_CastTo(ilGenerator, targetType);
            ilGenerator.Emit(OpCodes.Ldarg_1);
            Emit_CastTo(ilGenerator, valueType);

            Emit_Call(ilGenerator, setter);
            ilGenerator.Emit(OpCodes.Ret);

            return (PropertySetDelegate)dynamicMethod.CreateDelegate(typeof(PropertySetDelegate));
        }

19 Source : DynamicMethodRuntime.cs
with MIT License
from dotnet

private FactoryDelegate CreateFactoryDelegate(ConstructorInfo ctor)
        {
            DynamicMethod dynamicMethod = CreateDynamicMethod(ctor.DeclaringType.Name + "Ctor", 
                typeof(object), typeof(object[]));
            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

            LocalBuilder[] locals = LoadArguments(ilGenerator, ctor);
            ilGenerator.Emit(OpCodes.Newobj, ctor);
            UnloadArguments(ilGenerator, locals);
            ilGenerator.Emit(OpCodes.Ret);
            
            return (FactoryDelegate)dynamicMethod.CreateDelegate(typeof(FactoryDelegate));
        }

19 Source : DynamicMethodRuntime.cs
with MIT License
from dotnet

private FactoryDelegate CreateFactoryDelegate(MethodInfo factory)
        {
            DynamicMethod dynamicMethod = CreateDynamicMethod(factory.Name + "Factory", 
                typeof(object), typeof(object[]));
            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
            
            LocalBuilder[] locals = LoadArguments(ilGenerator, factory);
            ilGenerator.Emit(OpCodes.Call, factory);
            Emit_BoxIfValueType(ilGenerator, factory.ReturnType);
            UnloadArguments(ilGenerator, locals);
            ilGenerator.Emit(OpCodes.Ret);

            return (FactoryDelegate)dynamicMethod.CreateDelegate(typeof(FactoryDelegate));
        }

19 Source : DynamicMethodRuntime.cs
with MIT License
from dotnet

private PropertyGetDelegate CreateGetDelegate(MethodInfo getter)
        {
            DynamicMethod dynamicMethod = CreateDynamicMethod(getter.Name + "Getter", 
                typeof(object), typeof(object));
            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

            Type targetType = getter.IsStatic ? getter.GetParameters()[0].ParameterType : GetTargetType(getter);
            ilGenerator.Emit(OpCodes.Ldarg_0);
            Emit_CastTo(ilGenerator, targetType);
            
            Emit_Call(ilGenerator, getter);
            Emit_BoxIfValueType(ilGenerator, getter.ReturnType);
            ilGenerator.Emit(OpCodes.Ret);

            return (PropertyGetDelegate)dynamicMethod.CreateDelegate(typeof(PropertyGetDelegate));
        }

19 Source : DynamicMethodRuntime.cs
with MIT License
from dotnet

private DelegateCreator CreateDelegateCreatorWithoutHelper()
        {
            DynamicMethod dynamicMethod = CreateDynamicMethod("CreateDelegateHelper",
                typeof(Delegate), typeof(Type), typeof(object), typeof(string));
            ILGenerator ilGenerator = dynamicMethod.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldarg_1);
            ilGenerator.Emit(OpCodes.Ldarg_2);
            MethodInfo method = typeof(Delegate).GetMethod(KnownStrings.CreateDelegate,
                BindingFlags.Static | BindingFlags.Public, null, 
                new Type[] { typeof(Type), typeof(object), typeof(string) }, null);
            ilGenerator.Emit(OpCodes.Call, method);
            ilGenerator.Emit(OpCodes.Ret);

            return (DelegateCreator)dynamicMethod.CreateDelegate(typeof(DelegateCreator));
        }

19 Source : Program.cs
with MIT License
from dotnetcore

static void Main(string[] args)
        {
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            var action = FastMethodOperator.DefaultDomain()
                .Body("return 1+1;")
                .Return<int>()
                .Compile<Func<int>>();

            action();


            FakeMethodOperator.RandomDomain(item=> {
                item.replacedemblyName = "1";
                item.OutputToFile = true;
                })
               .UseMethod<TestB>("TestMethod")
               .StaticMethodBody($@"Console.WriteLine(""Hello World!"");")
               .Compile<Action>();


            FakeMethodOperator.RandomDomain(item => {
                item.replacedemblyName = "1";
                item.OutputToFile = true;
            })
                .UseMethod<TestB>("TestMethod")
                .MethodBody($@"Console.WriteLine(""Hello World!"");")
                .Compile<Action>(new TestA());

            


            /*
             *   在此之前,你需要右键,选择工程文件,在你的.csproj里面 
             *   
             *   写上这样一句浪漫的话: 
             *   
             *      <PreserveCompilationContext>true</PreserveCompilationContext>
             */

            //ProxyOperator<TestAbstract> abstractBuilder = new ProxyOperator<TestAbstract>();
            //abstractBuilder.OopName("UTestClreplaced");
            //abstractBuilder["GetName"] = "return Name;";
            //abstractBuilder["GetAge"] = "return Age;";
            //abstractBuilder.Compile();
            //var test = abstractBuilder.CreateProxy("UTestClreplaced");

            //var delegate2 = NDelegateOperator<GetterDelegate>.Delegate("return value.ToString();");
            //Console.WriteLine(delegate2(1));
            //var delegate3 = "return value.ToString();".Delegate<GetterDelegate>();
            //var delegateConvt = FastMethodOperator.Create()
            //    .Param<string>("value")
            //    .MethodBody($@"return value==""true"" || value==""mama"";")
            //    .Return<bool>()
            //    .Compile<Func<string, bool>>();

            //Console.WriteLine(delegateConvt("mama"));

           

            DynamicMethod method = new DynamicMethod("GetString", null, new Type[] { typeof(TestB), typeof(string) });
            ILGenerator il = method.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Stfld, typeof(TestB).GetField("Name"));
            il.Emit(OpCodes.Ret);
            var emitAction = (Action<TestB, string>)(method.CreateDelegate(typeof(Action<TestB, string>)));

            var roslynAction = FastMethodOperator.DefaultDomain()
                .Param<TestB>("instance")
                .Param<string>("value")
                .Body("instance.Name = value;")
                .Compile<Action<TestB, string>>();


            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Restart();
            for (int i = 0; i < 50000; i++)
            {
                var tEnreplacedy = new TestB();
                roslynAction(tEnreplacedy, "abc");
            }
            stopwatch.Stop();
            Console.WriteLine("Roslyn:\t" + stopwatch.Elapsed);

            stopwatch.Restart();
            for (int i = 0; i < 50000; i++)
            {
                var tEnreplacedy = new TestB();
                emitAction(tEnreplacedy,"abc");
            }
            stopwatch.Stop();
            Console.WriteLine("Emit:\t" + stopwatch.Elapsed);


            stopwatch.Restart();
            for (int i = 0; i < 50000; i++)
            {
                var tEnreplacedy = new TestB();
                roslynAction(tEnreplacedy, "abc");
            }
            stopwatch.Stop();
            Console.WriteLine("Roslyn:\t" + stopwatch.Elapsed);


            stopwatch.Restart();
            for (int i = 0; i < 50000; i++)
            {
                var tEnreplacedy = new TestB();
                emitAction(tEnreplacedy, "abc");
            }
            stopwatch.Stop();
            Console.WriteLine("Emit:\t" + stopwatch.Elapsed);







            Console.ReadKey();
        }

19 Source : DomainComponent.cs
with MIT License
from dotnetcore

public static void RegisterDefault<TDomain>(bool initializeReference = true) where TDomain : DomainBase
    {
        //Mark : 21M Memory
        if (initializeReference)
        {
#if DEBUG
            Stopwatch stopwatch = new();
            stopwatch.Start();
#endif
            //Mark1 : 89ms
            //Mark2 : 14ms
            Task.Run(() =>
            {

                ConcurrentDictionary<string, PortableExecutableReference> tempCache = new ConcurrentDictionary<string, PortableExecutableReference>();
                IEnumerable<string> paths = DependencyContext
                    .Default
                    .CompileLibraries.SelectMany(cl => cl.ResolveReferencePaths());
                Parallel.ForEach(paths,
                    asm => tempCache[Path.GetFileNameWithoutExtension(asm)] = MetadataReference.CreateFromFile(asm));
                while (DomainBase.DefaultDomain.Name == "init_fake_domain")
                {
                    Task.Delay(200);
                }
                Unsafe.AsRef(DomainBase.DefaultDomain.OtherReferencesFromFile) = tempCache;
            });
#if DEBUG
            stopwatch.StopAndShowCategoreInfo("[Reference]", "引用扫描", 1);
            stopwatch.Restart();
#endif
        }
#if DEBUG
            Stopwatch stopwatch2 = new();
            stopwatch2.Start();
#endif
            DynamicMethod method = new DynamicMethod("Domain" + Guid.NewGuid().ToString(), typeof(DomainBase), new Type[] { typeof(string) });
            ILGenerator il = method.GetILGenerator();
            ConstructorInfo ctor = typeof(TDomain).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(string) }, null)!;
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Newobj, ctor);
            il.Emit(OpCodes.Ret);
            DomainManagement.CreateDomain = (Func<string, DomainBase>)(method.CreateDelegate(typeof(Func<string, DomainBase>)));
            DomainManagement.Create("Default");

#if DEBUG
            stopwatch2.StopAndShowCategoreInfo("[Domain]", "域初始化", 1);
#endif

    }

19 Source : DynamicCallFieldTest.cs
with MIT License
from dotnetcore

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 = NDelegate.DefaultDomain().Func<CallModel, string>("return arg.Age;");
            NatashaGetString(OriginModel);
            OriginGetString = item => item.Age;
           

            NatashaGetDateTime = NDelegate.DefaultDomain().Func<CallModel, DateTime>("return arg.CreateTime;");
            NatashaGetDateTime(OriginModel);
            OriginGetDateTime = item => item.CreateTime;
            

            NatashaSetString = NDelegate.DefaultDomain().Action<CallModel, string>("arg1.Age=arg2;");
            NatashaSetString(OriginModel, OriginModel.Age);
           OriginSetString = (item, value) => item.Age = value;

            NatashaSetDateTime = DelegateOperator<ValueDelegate >.Delegate("model.CreateTime=value;");
            NatashaSetDateTime(OriginModel, OriginModel.CreateTime);
            OriginSetDateTime = OriginDateTime;

        }

19 Source : DynamicCallInitTest.cs
with MIT License
from dotnetcore

public void Precache()
        {
            DynamicMethod method = new DynamicMethod("Db" + Guid.NewGuid().ToString(), typeof(CallModel), new Type[0]);
            ILGenerator il = method.GetILGenerator();
            ConstructorInfo ctor = typeof(CallModel).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null);
            il.Emit(OpCodes.Newobj, ctor);
            il.Emit(OpCodes.Ret);
            EmitFunc = (Func<CallModel>)(method.CreateDelegate(typeof(Func<CallModel>)));
            NatashaFunc = NInstance.Creator<CallModel>();
        }

19 Source : DynamicCallPropertyTest.cs
with MIT License
from dotnetcore

public void Precache()
        {
            DynamicMethod method = new DynamicMethod("Advise", null, new Type[0]);
            ILGenerator il = method.GetILGenerator();
            var methods = typeof(CallModel).GetMethod("Runner", new Type[] { typeof(string) });
            il.Emit(OpCodes.Ldstr, "123");
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Call, methods);
            il.Emit(OpCodes.Call, methods);
            il.Emit(OpCodes.Ret);
            //return (Action)method.CreateDelegate(typeof(Action));
        }

19 Source : TypeDeserializer.cs
with Apache License 2.0
from dotnetcore

private static Func<IDataReaderDeserializer, ExecutionContext, object> CreateImpl(Type resultType)
        {
            var dynamicMethod = new DynamicMethod("CreateGetResult_" + Guid.NewGuid().ToString("N"), CommonType.Object,
                new[] {IDataReaderDeserializerType.Type, ExecutionContextType.Type});
            var ilGen = dynamicMethod.GetILGenerator();
            ilGen.LoadArg(0);
            ilGen.LoadArg(1);
            MethodInfo deserMethod;
            if (
                CommonType.IEnumerable.IsreplacedignableFrom(resultType)
                && resultType != CommonType.String)
            {
                var lisreplacedemType = resultType.GenericTypeArguments[0];
                deserMethod = IDataReaderDeserializerType.Method.MakeGenericToList(lisreplacedemType);
            }
            else
            {
                deserMethod = IDataReaderDeserializerType.Method.MakeGenericToSingle(resultType);
            }

            ilGen.Callvirt(deserMethod);
            if (resultType.IsValueType)
            {
                ilGen.Box(resultType);
            }

            ilGen.Return();
            return (Func<IDataReaderDeserializer, ExecutionContext, object>) dynamicMethod.CreateDelegate(
                typeof(Func<IDataReaderDeserializer, ExecutionContext, object>));
        }

19 Source : EmitSetAccessorFactory.cs
with Apache License 2.0
from dotnetcore

private Action<object, object> CreateImpl(PropertyInfo propertyInfo)
        {
            var dynamicMethod = new DynamicMethod("Set_" + Guid.NewGuid().ToString("N"), null, new[] { CommonType.Object, CommonType.Object }, propertyInfo.DeclaringType, true);
            var ilGen = dynamicMethod.GetILGenerator();
            ilGen.LoadArg(0);
            ilGen.LoadArg(1);
            if (propertyInfo.PropertyType.IsValueType)
            {
                ilGen.Unbox(propertyInfo.PropertyType);
                ilGen.LoadValueIndirect(propertyInfo.PropertyType);
            }
            ilGen.Call(propertyInfo.SetMethod);
            ilGen.Return();
            return (Action<object, object>)dynamicMethod.CreateDelegate(typeof(Action<object, object>));
        }

19 Source : EmitObjectFactoryBuilder.cs
with Apache License 2.0
from dotnetcore

public override Func<object[], object> Build(Type targetType, Type[] ctorArgTypes)
        {
            var dyMethodName = $"{targetType.Name}_{Guid.NewGuid():N}";

            DynamicMethod dyMethod = new DynamicMethod(dyMethodName, targetType, new Type[] {CommonType.ObjectArray},
                targetType, true);
            var ilGen = dyMethod.GetILGenerator();

            #region Init Arg

            for (int i = 0; i < ctorArgTypes.Length; i++)
            {
                Type argType = ctorArgTypes[i];
                ilGen.LoadArg(0);
                ilGen.LoadInt32(i);
                ilGen.LoadElement(CommonType.Object);
                if (argType.IsValueType)
                {
                    ilGen.Unbox(argType);
                    ilGen.LoadValueIndirect(argType);
                }
            }

            #endregion

            var targetCtor = GetConstructor(targetType, ctorArgTypes);
            ilGen.New(targetCtor);
            ilGen.Return();
            return (Func<object[], object>) dyMethod.CreateDelegate(typeof(Func<object[], object>));
        }

19 Source : EmitGetAccessorFactory.cs
with Apache License 2.0
from dotnetcore

private bool TryCreateImpl(Type targetType, PropertyTokenizer propertyTokenizer,
            out Func<object, object> getMethodImpl)
        {
            getMethodImpl = null;
            var dynamicMethod = new DynamicMethod("Get_" + Guid.NewGuid().ToString("N"), CommonType.Object,
                new[] {CommonType.Object}, targetType, true);
            var ilGen = dynamicMethod.GetILGenerator();
            ilGen.LoadArg(0);
            var propertyType = targetType;
            do
            {
                 var current = propertyTokenizer.Current;
                switch (current.Mode)
                {
                    case AccessMode.Get:
                    {
                        var propertyInfo = propertyType.GetProperty(current.Name);

                        if (propertyInfo == null)
                        {
                            return false;
                        }

                        ilGen.Call(propertyInfo.GetMethod);
                        propertyType = propertyInfo.PropertyType;
                        if (propertyType.IsValueType)
                        {
                            ilGen.Box(propertyType);
                        }

                        break;
                    }

                    case AccessMode.IndexerGet:
                    {
                        var propertyInfo = propertyType.GetProperty(current.Name);
                        if (propertyInfo == null)
                        {
                            return false;
                        }

                        ilGen.Call(propertyInfo.GetMethod);

                        MethodInfo indexerGet;
                        if (propertyInfo.PropertyType.IsArray)
                        {
                            indexerGet = propertyInfo.PropertyType.GetMethod("Get", new[] {CommonType.Int32});
                        }
                        else
                        {
                            indexerGet = propertyInfo.PropertyType.GetMethod("get_Item");
                        }

                        if (indexerGet == null)
                        {
                            throw new SmartSqlException($"can not find Get Indexer:{propertyInfo.PropertyType}");
                        }


                        var indexerGetParamType = indexerGet.GetParameters().First().ParameterType;

                        if (indexerGetParamType == CommonType.String)
                        {
                            ilGen.LoadString(current.Index);
                        }
                        else if (indexerGetParamType == CommonType.Int32)
                        {
                            if (!Int32.TryParse(current.Index, out var idx))
                            {
                                throw new SmartSqlException($"Index:[{current.Index}] can not convert to Int32.");
                            }

                            ilGen.LoadInt32(idx);
                        }

                        ilGen.Call(indexerGet);
                        propertyType = indexerGet.ReturnType;
                        if (propertyType.IsValueType)
                        {
                            ilGen.Box(propertyType);
                        }

                        break;
                    }
                }
            } while (propertyTokenizer.MoveNext());

            ilGen.Return();
            getMethodImpl = (Func<object, object>) dynamicMethod.CreateDelegate(typeof(Func<object, object>));
            return true;
        }

19 Source : EntityDeserializer.cs
with Apache License 2.0
from dotnetcore

private Delegate CreateDeserialize<TResult>(ExecutionContext executionContext)
        {
            var resultType = typeof(TResult);
            if (executionContext.Request.EnablePropertyChangedTrack == true)
            {
                if (resultType.GetProperties().Any(p => !p.SetMethod.IsVirtual))
                {
                    _logger.LogWarning(
                        $"Type:{resultType.FullName} contain Non-Virtual Method,can not be enhanced by EnreplacedyProxy!");
                }
                else
                {
                    resultType = EnreplacedyProxyCache<TResult>.ProxyType;
                }
            }

            var dataReader = executionContext.DataReaderWrapper;
            var resultMap = executionContext.Request.GetCurrentResultMap();

            var constructorMap = resultMap?.Constructor;
            var columns = Enumerable.Range(0, dataReader.FieldCount)
                .Select(i => new ColumnDescriptor
                {
                    Index = i,
                    ColumnName = dataReader.GetName(i),
                    PropertyName = executionContext.Request.AutoConverter.Convert(dataReader.GetName(i)),
                    FieldType = dataReader.GetFieldType(i)
                })
                .ToDictionary(col => col.ColumnName);

            var deserFunc = new DynamicMethod("Deserialize" + Guid.NewGuid().ToString("N"), resultType,
                new[] {DataType.DataReaderWrapper, RequestContextType.AbstractType}, resultType, true);
            var ilGen = deserFunc.GetILGenerator();
            ilGen.DeclareLocal(resultType); // return value
            ilGen.DeclareLocal(CommonType.Int32); // current column index
            ilGen.DeclareLocal(CommonType.String); // current column name
            ilGen.DeclareLocal(CommonType.String); // current Property.Name

            #region New

            ConstructorInfo resultCtor = null;
            if (constructorMap == null)
            {
                resultCtor = resultType.GetConstructor(
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
            }
            else
            {
                var ctorArgTypes = constructorMap.Args.Select(arg => arg.CSharpType).ToArray();
                resultCtor = resultType.GetConstructor(
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, ctorArgTypes, null);
                foreach (var arg in constructorMap.Args)
                {
                    var col = columns[arg.Column];
                    StoreLocalColumnIndex(ilGen, col.Index);
                    LoadPropertyValue(ilGen, executionContext, arg.CSharpType, col.FieldType, null);
                }
            }

            if (resultCtor == null)
            {
                throw new SmartSqlException(
                    $"No parameterless constructor defined for the target type: [{resultType.FullName}]");
            }

            ilGen.New(resultCtor);

            #endregion

            ilGen.StoreLocalVar(0);

            var ignoreDbNull = executionContext.SmartSqlConfig.Settings.IgnoreDbNull;

            ilGen.BeginExceptionBlock();
            foreach (var col in columns)
            {
                #region Ensure Property & TypeHanlder

                if (!ResolveProperty<TResult>(resultMap, resultType, col.Value, out var propertyHolder)
                )
                {
                    continue;
                }

                if (!propertyHolder.CanWrite)
                {
                    continue;
                }

                #endregion

                var columnDescriptor = col.Value;
                var colIndex = columnDescriptor.Index;
                StoreLocalColumnIndex(ilGen, colIndex);
                StoreLocalColumnName(ilGen, col.Value.ColumnName);
                StoreLocalPropertyName(ilGen, propertyHolder.Property.Name);
                var isDbNullLabel = ilGen.DefineLabel();

                var propertyType = propertyHolder.PropertyType;
                if (ignoreDbNull)
                {
                    ilGen.LoadArg(0);
                    LoadLocalColumnIndex(ilGen);
                    ilGen.Call(DataType.Method.IsDBNull);
                    ilGen.IfTrueS(isDbNullLabel);
                }

                ilGen.LoadLocalVar(0);
                LoadPropertyValue(ilGen, executionContext, propertyType, columnDescriptor.FieldType,
                    propertyHolder.TypeHandler);
                ilGen.Call(propertyHolder.SetMethod);
                if (ignoreDbNull)
                {
                    ilGen.MarkLabel(isDbNullLabel);
                }
            }

            ilGen.BeginCatchBlock(typeof(Exception));

            ilGen.LoadLocalVar(0);
            LoadLocalColumnIndex(ilGen);
            LoadLocalColumnName(ilGen);
            LoadLocalPropertyName(ilGen);
            ilGen.LoadArg(0);
            ilGen.EmitCall(OpCodes.Call, THROW_DESERIALIZE_EXCEPTION, null);
            ilGen.EndExceptionBlock();
            if (typeof(IEnreplacedyPropertyChangedTrackProxy).IsreplacedignableFrom(resultType))
            {
                ilGen.LoadLocalVar(0);
                ilGen.LoadInt32(1);
                var setEnableTrackMethod =
                    resultType.GetMethod(nameof(IEnreplacedyPropertyChangedTrackProxy.SetEnablePropertyChangedTrack));
                ilGen.Call(setEnableTrackMethod);
            }

            ilGen.LoadLocalVar(0);
            ilGen.Return();
            return deserFunc.CreateDelegate(typeof(Func<DataReaderWrapper, AbstractRequestContext, TResult>));
        }

19 Source : RequestConvertCache.cs
with Apache License 2.0
from dotnetcore

private static Func<object, SqlParameterCollection> BuildConvert()
        {
            var requestType = typeof(TRequest);
            var sourceProps = requestType.GetProperties().Where(p => p.CanRead);
            var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString("N"), SqlParameterType.SqlParameterCollection,
                new[] {CommonType.Object}, requestType, true);
            var ilGen = dynamicMethod.GetILGenerator();
            ilGen.DeclareLocal(SqlParameterType.SqlParameterCollection);
            var ignoreCase = typeof(TIgnoreCase) == typeof(IgnoreCaseType);
            ilGen.LoadInt32(ignoreCase ? 1 : 0);
            ilGen.New(SqlParameterType.Ctor.SqlParameterCollection);
            ilGen.StoreLocalVar(0);
            foreach (var prop in sourceProps)
            {
                ilGen.LoadLocalVar(0);
                ilGen.LoadString(prop.Name);
                ilGen.LoadArg(0);
                ilGen.Call(prop.GetMethod);
                if (prop.PropertyType.IsValueType)
                {
                    ilGen.Box(prop.PropertyType);
                }

                ilGen.LoadType(prop.PropertyType);
                ilGen.New(SqlParameterType.Ctor.SqlParameter);

                #region  Ensure TypeHanlder

                ilGen.Dup();
                var column = prop.GetCustomAttribute<ColumnAttribute>();
                if (column != null && !String.IsNullOrEmpty(column.TypeHandler))
                {
                    var typeHandlerField =
                        NamedTypeHandlerCache.GetTypeHandlerField(column.Alias, column.TypeHandler);
                    if (typeHandlerField == null)
                    {
                        throw new SmartSqlException(
                            $"Can not find NamedTypeHandler SmartSql.Alias:[{column.Alias}],Name :[{column.TypeHandler}].");
                    }

                    ilGen.FieldGet(typeHandlerField);
                }
                else
                {
                    MethodInfo getHandlerMethod = null;
                    if (column?.FieldType != null)
                    {
                        getHandlerMethod = TypeHandlerCacheType.GetHandlerMethod(prop.PropertyType, column.FieldType);
                    }

                    if (getHandlerMethod == null)
                    {
                        getHandlerMethod = PropertyTypeHandlerCacheType.GetHandlerMethod(prop.PropertyType);
                    }

                    ilGen.Call(getHandlerMethod);
                }

                ilGen.Call(SqlParameterType.Method.SetTypeHandler);
                ilGen.Call(SqlParameterType.Method.Add);

                #endregion
            }

            ilGen.LoadLocalVar(0);
            ilGen.Return();
            return (Func<object, SqlParameterCollection>) dynamicMethod.CreateDelegate(
                typeof(Func<object, SqlParameterCollection>));
        }

19 Source : EmitGetAccessorFactory.cs
with Apache License 2.0
from dotnetcore

private Func<object, object> CreateImpl(PropertyInfo propertyInfo)
        {
            if (propertyInfo.GetMethod == null)
            {
                throw new SmartSqlException(
                    $"Can not find GetMethod -> Type:[{propertyInfo.DeclaringType.FullName}],PropertyInfo :[{propertyInfo.Name}]. ");
            }

            var dynamicMethod = new DynamicMethod("Get_" + Guid.NewGuid().ToString("N"), CommonType.Object,
                new[] {CommonType.Object}, propertyInfo.DeclaringType, true);
            var ilGen = dynamicMethod.GetILGenerator();
            ilGen.LoadArg(0);
            ilGen.Call(propertyInfo.GetMethod);
            if (propertyInfo.PropertyType.IsValueType)
            {
                ilGen.Box(propertyInfo.PropertyType);
            }

            ilGen.Return();
            return (Func<object, object>) dynamicMethod.CreateDelegate(typeof(Func<object, object>));
        }

19 Source : CreateInstanceFunc_Test.cs
with Apache License 2.0
from dotnetcore

public Func<object[], object> ILGenerator(Type _targetType)
        {
            DynamicMethod dyMethod = new DynamicMethod("NewGenericList", _targetType, new Type[] { CommonType.ObjectArray }, _targetType, true);
            var ilGen = dyMethod.GetILGenerator();
            var newCtor = _targetType.GetConstructor(Type.EmptyTypes);
            ilGen.New(newCtor);
            ilGen.Return();
            return (Func<object[], object>)dyMethod.CreateDelegate(typeof(Func<object[], object>));
        }

19 Source : Tests.cs
with Apache License 2.0
from dotnetcore

[Fact]
        public void BuildNewUser_Func_IL()
        {
            var _targetType = typeof(User);
            DynamicMethod dyMethod = new DynamicMethod("NewGenericList", _targetType, new Type[] { CommonType.ObjectArray }, _targetType, true);

            var ilGen = dyMethod.GetILGenerator();
            var newCtor = _targetType.GetConstructor(Type.EmptyTypes);
            ilGen.New(newCtor);
            ilGen.Return();
            //var funcType = Expression.GetFuncType(CommonType.ArrayObject,_targetType);
            var func = (Func<object[], object>)dyMethod.CreateDelegate(typeof(Func<object[], object>));
            var user = func(null) as User;
            replacedert.NotNull(user);
        }

19 Source : FastInvokeHandler.cs
with Apache License 2.0
from dotnetcore

public static InvokeHandler Create(MethodInfo methodInfo)
        {
            if (methodInfo.DeclaringType == null)
            {
                throw new InvalidOperationException("methodInfo的类型为空。");
            }
            DynamicMethod dynamicMethod = new DynamicMethod(string.Empty,
                typeof(object),
                new[] { 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++)
            {
                il.Emit(ps[i].ParameterType.IsByRef ? OpCodes.Ldloca_S : OpCodes.Ldloc, locals[i]);
            }
            il.EmitCall(methodInfo.IsStatic ? OpCodes.Call : 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);
            InvokeHandler invoker = (InvokeHandler)dynamicMethod.CreateDelegate(typeof(InvokeHandler));
            return invoker;
        }

19 Source : ValueTupleConvert.cs
with Apache License 2.0
from dotnetcore

private static Func<object[], object> CreateImpl(Type valueTupleType)
        {
            var genericTypeArguments = valueTupleType.GenericTypeArguments;
            var createVT = CommonType.GetValueTupleCreateMethod(genericTypeArguments);
            var dynamicMethod = new DynamicMethod("ValueTupleConvert_" + Guid.NewGuid().ToString("N"), CommonType.Object, new[] { CommonType.ObjectArray });

            var ilGen = dynamicMethod.GetILGenerator();
            for (int i = 0; i < genericTypeArguments.Length; i++)
            {
                Type argType = genericTypeArguments[i];
                ilGen.LoadArg(0);
                ilGen.LoadInt32(i);
                ilGen.LoadElement(CommonType.Object);
                if (argType.IsValueType)
                {
                    ilGen.Unbox(argType);
                    ilGen.LoadValueIndirect(argType);
                }
            }
            ilGen.Emit(OpCodes.Call, createVT);
            ilGen.Box(valueTupleType);
            ilGen.Return();
            return (Func<object[], object>)dynamicMethod.CreateDelegate(typeof(Func<object[], object>));
        }

19 Source : EventAdapter.cs
with Apache License 2.0
from duwenjie15

private DynamicMethod BuildBridge()
        {
            MethodInfo methodInfo = typeof(TCallback).GetMethod("Invoke");
            ParameterInfo[] parameterInfos = methodInfo.GetParameters();

            //Get parameterTyps
            Type[] parameterTypes = new Type[parameterInfos.Length + 1];
            parameterTypes[0] = GetType();
            for (int i = 0; i < parameterInfos.Length; i++) parameterTypes[i + 1] = parameterInfos[i].ParameterType;

            DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, methodInfo.ReturnType, parameterTypes, GetType(), true);
            ILGenerator iLGenerator = dynamicMethod.GetILGenerator();


            LocalBuilder handler = iLGenerator.DeclareLocal(typeof(Handler));
            LocalBuilder eventObj = iLGenerator.DeclareLocal(typeof(TEventArgs));

            //LabelEnd
            Label end = iLGenerator.DefineLabel();
            //Read handler
            //Push this to stack
            iLGenerator.PushThisCallRefWithObject(GetType());
            iLGenerator.Push(GetType().GetField(nameof(_handler), BindingFlags.NonPublic | BindingFlags.Instance));
            iLGenerator.Pop(handler);
            iLGenerator.Push(handler);
            iLGenerator.Emit(OpCodes.Brfalse_S, end);

            //New eventObj
            Type eventType = typeof(TEventArgs);
            iLGenerator.Emit(OpCodes.Newobj, eventType.GetConstructor(new Type[0]));

            //Stacktop eventObj
            //Map
            Map retMap = null;
            Map[] maps = MappingCache.GetMap(eventType, parameterInfos);
            foreach (Map map in maps)
            {
                if (map.IsRet)
                {
                    retMap = map;
                    continue;
                }
                //Copy stacktop
                iLGenerator.Emit(OpCodes.Dup);
                //+1 because first parameter is this
                iLGenerator.PushArgument(map.ParameterIndex + 1);
                Type sType = map.ParameterInfo.ParameterType;
                if (sType.IsByRef)
                {
                    iLGenerator.UnRef(sType);
                    sType = sType.GetElementType();
                }

                if (map.MemberInfo is PropertyInfo propertyInfo)
                {
                    iLGenerator.Convert(sType, propertyInfo.PropertyType);
                    iLGenerator.Call(propertyInfo.GetSetMethod(true));
                }
                else if (map.MemberInfo is FieldInfo fieldInfo)
                {
                    iLGenerator.Convert(sType, fieldInfo.FieldType);
                    iLGenerator.Pop(fieldInfo);
                }
            }

            iLGenerator.Pop(eventObj);

            iLGenerator.Push(handler);
            iLGenerator.PushThisCallRefWithObject(GetType());
            iLGenerator.Push(GetType().GetField(nameof(_miniblinkProxy), BindingFlags.NonPublic | BindingFlags.Instance));
            iLGenerator.Push(eventObj);
            iLGenerator.Call(typeof(Handler).GetMethod(nameof(Handler.Invoke)));

            foreach (Map map in maps)
            {
                if (map.IsRef)
                {
                    iLGenerator.PushArgument(map.ParameterIndex + 1);
                    iLGenerator.Push(eventObj);

                    if (map.MemberInfo is PropertyInfo propertyInfo)
                    {
                        iLGenerator.Emit(OpCodes.Callvirt, propertyInfo.GetGetMethod());
                        iLGenerator.Convert(propertyInfo.PropertyType, map.ParameterInfo.ParameterType.GetElementType());
                    }
                    else if (map.MemberInfo is FieldInfo fieldInfo)
                    {
                        iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
                        iLGenerator.Convert(fieldInfo.FieldType, map.ParameterInfo.ParameterType.GetElementType());
                    }
                    iLGenerator.TransferRef(map.ParameterInfo.ParameterType);
                }
            }

            if (retMap != null && methodInfo.ReturnType != typeof(void))
            {
                iLGenerator.Push(eventObj);
                if (retMap.MemberInfo is PropertyInfo propertyInfo)
                {
                    iLGenerator.Call(propertyInfo.GetGetMethod(true));
                    iLGenerator.Convert(propertyInfo.PropertyType, methodInfo.ReturnType);
                }
                else if (retMap.MemberInfo is FieldInfo fieldInfo)
                {
                    iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
                    iLGenerator.Convert(fieldInfo.FieldType, methodInfo.ReturnType);
                }
                iLGenerator.Ret();
            }

            iLGenerator.MarkLabel(end);
            //Default Ret
            if (methodInfo.ReturnType != typeof(void))
                iLGenerator.CreateDefault(methodInfo.ReturnType);
            iLGenerator.Ret();
            return dynamicMethod;
        }

19 Source : MSILGenerator.cs
with MIT License
from elastacloud

public replacedignArrayDelegate Generatereplacedigner(DataColumn dataColumn, Type clreplacedType)
      {
         DataField field = dataColumn.Field;

         Type[] methodArgs = { typeof(DataColumn), typeof(Array) };
         var runMethod = new DynamicMethod(
            $"Set{clreplacedType.Name}{field.Name}",
            typeof(void),
            methodArgs,
            GetType().GetTypeInfo().Module);

         ILGenerator il = runMethod.GetILGenerator();

         //set clreplaced property method
         TypeInfo ti = clreplacedType.GetTypeInfo();
         PropertyInfo pi = ti.GetDeclaredProperty(field.ClrPropName ?? field.Name);
         MethodInfo setValueMethod = pi.SetMethod;

         TypeInfo dcti = dataColumn.GetType().GetTypeInfo();
         MethodInfo getDataMethod = dcti.GetDeclaredProperty(nameof(DataColumn.Data)).GetMethod;
         MethodInfo getRepsMethod = dcti.GetDeclaredProperty(nameof(DataColumn.RepereplacedionLevels)).GetMethod;

         TypeConversion conversion = GetConversion(dataColumn.Field.ClrNullableIfHasNullsType, pi.PropertyType);

         Generatereplacedigner(il, clreplacedType, field,
            setValueMethod,
            getDataMethod,
            getRepsMethod,
            conversion);

         return (replacedignArrayDelegate)runMethod.CreateDelegate(typeof(replacedignArrayDelegate));
      }

19 Source : IntegrationMapper.cs
with Apache License 2.0
from elastic

internal static DynamicMethod CreateBeginMethodDelegate(Type integrationType, Type targetType, Type[] argumentsTypes)
        {
            /*
             * OnMethodBegin signatures with 1 or more parameters with 1 or more generics:
             *      - CallTargetState OnMethodBegin<TTarget>(TTarget instance);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1>(TTarget instance, TArg1 arg1);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1, TArg2>(TTarget instance, TArg1 arg1, TArg2);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1, TArg2, ...>(TTarget instance, TArg1 arg1, TArg2, ...);
             *      - CallTargetState OnMethodBegin<TTarget>();
             *      - CallTargetState OnMethodBegin<TTarget, TArg1>(TArg1 arg1);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1, TArg2>(TArg1 arg1, TArg2);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1, TArg2, ...>(TArg1 arg1, TArg2, ...);
             *
             */

            Logger.Debug($"Creating BeginMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}]");
            var onMethodBeginMethodInfo = integrationType.GetMethod(BeginMethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
            if (onMethodBeginMethodInfo is null)
            {
				Logger.Debug($"'{BeginMethodName}' method was not found in integration type: '{integrationType.FullName}'.");
                return null;
            }

            if (onMethodBeginMethodInfo.ReturnType != typeof(CallTargetState))
				throw new ArgumentException($"The return type of the method: {BeginMethodName} in type: {integrationType.FullName} is not {nameof(CallTargetState)}");

			var genericArgumentsTypes = onMethodBeginMethodInfo.GetGenericArguments();
            if (genericArgumentsTypes.Length < 1)
				throw new ArgumentException($"The method: {BeginMethodName} in type: {integrationType.FullName} doesn't have the generic type for the instance type.");

			var onMethodBeginParameters = onMethodBeginMethodInfo.GetParameters();
            if (onMethodBeginParameters.Length < argumentsTypes.Length)
				throw new ArgumentException($"The method: {BeginMethodName} with {onMethodBeginParameters.Length} parameters in type: {integrationType.FullName} has less parameters than required.");
			else if (onMethodBeginParameters.Length > argumentsTypes.Length + 1)
				throw new ArgumentException($"The method: {BeginMethodName} with {onMethodBeginParameters.Length} parameters in type: {integrationType.FullName} has more parameters than required.");
			else if (onMethodBeginParameters.Length != argumentsTypes.Length && onMethodBeginParameters[0].ParameterType != genericArgumentsTypes[0]) throw new ArgumentException($"The first generic argument for method: {BeginMethodName} in type: {integrationType.FullName} must be the same as the first parameter for the instance value.");

			var callGenericTypes = new List<Type>();

            var mustLoadInstance = onMethodBeginParameters.Length != argumentsTypes.Length;
            var instanceGenericType = genericArgumentsTypes[0];
            var instanceGenericConstraint = instanceGenericType.GetGenericParameterConstraints().FirstOrDefault();
            Type instanceProxyType = null;
            if (instanceGenericConstraint != null)
            {
                var result = DuckType.GetOrCreateProxyType(instanceGenericConstraint, targetType);
                instanceProxyType = result.ProxyType;
                callGenericTypes.Add(instanceProxyType);
            }
            else
				callGenericTypes.Add(targetType);

			var callMethod = new DynamicMethod(
				$"{onMethodBeginMethodInfo.DeclaringType.Name}.{onMethodBeginMethodInfo.Name}",
				typeof(CallTargetState),
				new Type[] { targetType }.Concat(argumentsTypes).ToArray(),
				onMethodBeginMethodInfo.Module,
				true);

            var ilWriter = callMethod.GetILGenerator();

            // Load the instance if is needed
            if (mustLoadInstance)
            {
                ilWriter.Emit(OpCodes.Ldarg_0);

                if (instanceGenericConstraint != null)
					WriteCreateNewProxyInstance(ilWriter, instanceProxyType, targetType);
			}

            // Load arguments
            for (var i = mustLoadInstance ? 1 : 0; i < onMethodBeginParameters.Length; i++)
            {
                var sourceParameterType = argumentsTypes[mustLoadInstance ? i - 1 : i];
                var targetParameterType = onMethodBeginParameters[i].ParameterType;
                Type targetParameterTypeConstraint = null;
                Type parameterProxyType = null;

                if (targetParameterType.IsGenericParameter)
                {
                    targetParameterType = genericArgumentsTypes[targetParameterType.GenericParameterPosition];
                    targetParameterTypeConstraint = targetParameterType.GetGenericParameterConstraints().FirstOrDefault(pType => pType != typeof(IDuckType));
                    if (targetParameterTypeConstraint is null)
						callGenericTypes.Add(sourceParameterType);
					else
                    {
                        var result = DuckType.GetOrCreateProxyType(targetParameterTypeConstraint, sourceParameterType);
                        parameterProxyType = result.ProxyType;
                        callGenericTypes.Add(parameterProxyType);
                    }
                }
                else if (!targetParameterType.IsreplacedignableFrom(sourceParameterType) && (!(sourceParameterType.IsEnum && targetParameterType.IsEnum)))
					throw new InvalidCastException($"The target parameter {targetParameterType} can't be replacedigned from {sourceParameterType}");

				WriteLoadArgument(ilWriter, i, mustLoadInstance);
                if (parameterProxyType != null)
                {
                    WriteCreateNewProxyInstance(ilWriter, parameterProxyType, sourceParameterType);
                }
            }

            // Call method
            onMethodBeginMethodInfo = onMethodBeginMethodInfo.MakeGenericMethod(callGenericTypes.ToArray());
            ilWriter.EmitCall(OpCodes.Call, onMethodBeginMethodInfo, null);
            ilWriter.Emit(OpCodes.Ret);

            Logger.Debug($"Created BeginMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}]");
            return callMethod;
        }

19 Source : IntegrationMapper.cs
with Apache License 2.0
from elastic

internal static DynamicMethod CreateSlowBeginMethodDelegate(Type integrationType, Type targetType)
        {
            /*
             * OnMethodBegin signatures with 1 or more parameters with 1 or more generics:
             *      - CallTargetState OnMethodBegin<TTarget>(TTarget instance);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1>(TTarget instance, TArg1 arg1);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1, TArg2>(TTarget instance, TArg1 arg1, TArg2);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1, TArg2, ...>(TTarget instance, TArg1 arg1, TArg2, ...);
             *      - CallTargetState OnMethodBegin<TTarget>();
             *      - CallTargetState OnMethodBegin<TTarget, TArg1>(TArg1 arg1);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1, TArg2>(TArg1 arg1, TArg2);
             *      - CallTargetState OnMethodBegin<TTarget, TArg1, TArg2, ...>(TArg1 arg1, TArg2, ...);
             *
             */

            Logger.Debug($"Creating SlowBeginMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}]");
            var onMethodBeginMethodInfo = integrationType.GetMethod(BeginMethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
            if (onMethodBeginMethodInfo is null)
            {
				Logger.Debug($"'{BeginMethodName}' method was not found in integration type: '{integrationType.FullName}'.");
                return null;
            }

            if (onMethodBeginMethodInfo.ReturnType != typeof(CallTargetState))
				throw new ArgumentException($"The return type of the method: {BeginMethodName} in type: {integrationType.FullName} is not {nameof(CallTargetState)}");

			var genericArgumentsTypes = onMethodBeginMethodInfo.GetGenericArguments();
            if (genericArgumentsTypes.Length < 1)
				throw new ArgumentException($"The method: {BeginMethodName} in type: {integrationType.FullName} doesn't have the generic type for the instance type.");

			var onMethodBeginParameters = onMethodBeginMethodInfo.GetParameters();

            var callGenericTypes = new List<Type>();

            var mustLoadInstance = onMethodBeginParameters[0].ParameterType.IsGenericParameter && onMethodBeginParameters[0].ParameterType.GenericParameterPosition == 0;
            var instanceGenericType = genericArgumentsTypes[0];
            var instanceGenericConstraint = instanceGenericType.GetGenericParameterConstraints().FirstOrDefault();
            Type instanceProxyType = null;
            if (instanceGenericConstraint != null)
            {
                var result = DuckType.GetOrCreateProxyType(instanceGenericConstraint, targetType);
                instanceProxyType = result.ProxyType;
                callGenericTypes.Add(instanceProxyType);
            }
            else
				callGenericTypes.Add(targetType);

			var callMethod = new DynamicMethod(
                     $"{onMethodBeginMethodInfo.DeclaringType.Name}.{onMethodBeginMethodInfo.Name}",
                     typeof(CallTargetState),
                     new Type[] { targetType, typeof(object[]) },
                     onMethodBeginMethodInfo.Module,
                     true);

            var ilWriter = callMethod.GetILGenerator();

            // Load the instance if is needed
            if (mustLoadInstance)
            {
                ilWriter.Emit(OpCodes.Ldarg_0);

                if (instanceGenericConstraint != null)
                {
                    WriteCreateNewProxyInstance(ilWriter, instanceProxyType, targetType);
                }
            }

            // Load arguments
            for (var i = mustLoadInstance ? 1 : 0; i < onMethodBeginParameters.Length; i++)
            {
                var targetParameterType = onMethodBeginParameters[i].ParameterType;
                Type targetParameterTypeConstraint = null;

                if (targetParameterType.IsGenericParameter)
                {
                    targetParameterType = genericArgumentsTypes[targetParameterType.GenericParameterPosition];

                    targetParameterTypeConstraint = targetParameterType.GetGenericParameterConstraints().FirstOrDefault(pType => pType != typeof(IDuckType));
                    if (targetParameterTypeConstraint is null)
						callGenericTypes.Add(typeof(object));
					else
                    {
                        targetParameterType = targetParameterTypeConstraint;
                        callGenericTypes.Add(targetParameterTypeConstraint);
                    }
                }

                ilWriter.Emit(OpCodes.Ldarg_1);
                WriteIntValue(ilWriter, i - (mustLoadInstance ? 1 : 0));
                ilWriter.Emit(OpCodes.Ldelem_Ref);

                if (targetParameterTypeConstraint != null)
					ilWriter.EmitCall(OpCodes.Call, ConvertTypeMethodInfo.MakeGenericMethod(targetParameterTypeConstraint), null);
				else if (targetParameterType.IsValueType)
					ilWriter.Emit(OpCodes.Unbox_Any, targetParameterType);
			}

            // Call method
            onMethodBeginMethodInfo = onMethodBeginMethodInfo.MakeGenericMethod(callGenericTypes.ToArray());
            ilWriter.EmitCall(OpCodes.Call, onMethodBeginMethodInfo, null);
            ilWriter.Emit(OpCodes.Ret);

            Logger.Debug($"Created SlowBeginMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}]");
            return callMethod;
        }

19 Source : IntegrationMapper.cs
with Apache License 2.0
from elastic

internal static DynamicMethod CreateEndMethodDelegate(Type integrationType, Type targetType, Type returnType)
        {
            /*
             * OnMethodEnd signatures with 3 or 4 parameters with 1 or 2 generics:
             *      - CallTargetReturn<TReturn> OnMethodEnd<TTarget, TReturn>(TTarget instance, TReturn returnValue, Exception exception, CallTargetState state);
             *      - CallTargetReturn<TReturn> OnMethodEnd<TTarget, TReturn>(TReturn returnValue, Exception exception, CallTargetState state);
             *      - CallTargetReturn<[Type]> OnMethodEnd<TTarget>([Type] returnValue, Exception exception, CallTargetState state);
             *
             */

			Logger.Debug($"Creating EndMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}, ReturnType={returnType.FullName}]");
            var onMethodEndMethodInfo = integrationType.GetMethod(EndMethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
            if (onMethodEndMethodInfo is null)
            {
				Logger.Debug($"'{EndMethodName}' method was not found in integration type: '{integrationType.FullName}'.");
                return null;
            }

            if (onMethodEndMethodInfo.ReturnType.GetGenericTypeDefinition() != typeof(CallTargetReturn<>))
				throw new ArgumentException($"The return type of the method: {EndMethodName} in type: {integrationType.FullName} is not {nameof(CallTargetReturn)}");

			var genericArgumentsTypes = onMethodEndMethodInfo.GetGenericArguments();
            if (genericArgumentsTypes.Length < 1 || genericArgumentsTypes.Length > 2)
				throw new ArgumentException($"The method: {EndMethodName} in type: {integrationType.FullName} must have the generic type for the instance type.");

			var onMethodEndParameters = onMethodEndMethodInfo.GetParameters();
            if (onMethodEndParameters.Length < 3)
				throw new ArgumentException($"The method: {EndMethodName} with {onMethodEndParameters.Length} parameters in type: {integrationType.FullName} has less parameters than required.");
			else if (onMethodEndParameters.Length > 4)
				throw new ArgumentException($"The method: {EndMethodName} with {onMethodEndParameters.Length} parameters in type: {integrationType.FullName} has more parameters than required.");

			if (onMethodEndParameters[onMethodEndParameters.Length - 2].ParameterType != typeof(Exception))
				throw new ArgumentException($"The Exception type parameter of the method: {EndMethodName} in type: {integrationType.FullName} is missing.");

			if (onMethodEndParameters[onMethodEndParameters.Length - 1].ParameterType != typeof(CallTargetState))
				throw new ArgumentException($"The CallTargetState type parameter of the method: {EndMethodName} in type: {integrationType.FullName} is missing.");

			var callGenericTypes = new List<Type>();

            var mustLoadInstance = onMethodEndParameters.Length == 4;
            var instanceGenericType = genericArgumentsTypes[0];
            var instanceGenericConstraint = instanceGenericType.GetGenericParameterConstraints().FirstOrDefault();
            Type instanceProxyType = null;
            if (instanceGenericConstraint != null)
            {
                var result = DuckType.GetOrCreateProxyType(instanceGenericConstraint, targetType);
                instanceProxyType = result.ProxyType;
                callGenericTypes.Add(instanceProxyType);
            }
            else
				callGenericTypes.Add(targetType);

			var returnParameterIndex = onMethodEndParameters.Length == 4 ? 1 : 0;
            var isAGenericReturnValue = onMethodEndParameters[returnParameterIndex].ParameterType.IsGenericParameter;
            Type returnValueGenericType = null;
            Type returnValueGenericConstraint = null;
            Type returnValueProxyType = null;
            if (isAGenericReturnValue)
            {
                returnValueGenericType = genericArgumentsTypes[1];
                returnValueGenericConstraint = returnValueGenericType.GetGenericParameterConstraints().FirstOrDefault();
                if (returnValueGenericConstraint != null)
                {
                    var result = DuckType.GetOrCreateProxyType(returnValueGenericConstraint, returnType);
                    returnValueProxyType = result.ProxyType;
                    callGenericTypes.Add(returnValueProxyType);
                }
                else
                {
                    callGenericTypes.Add(returnType);
                }
            }
            else if (onMethodEndParameters[returnParameterIndex].ParameterType != returnType)
            {
                throw new ArgumentException($"The ReturnValue type parameter of the method: {EndMethodName} in type: {integrationType.FullName} is invalid. [{onMethodEndParameters[returnParameterIndex].ParameterType} != {returnType}]");
            }

            var callMethod = new DynamicMethod(
                     $"{onMethodEndMethodInfo.DeclaringType.Name}.{onMethodEndMethodInfo.Name}.{targetType.Name}.{returnType.Name}",
                     typeof(CallTargetReturn<>).MakeGenericType(returnType),
                     new Type[] { targetType, returnType, typeof(Exception), typeof(CallTargetState) },
                     onMethodEndMethodInfo.Module,
                     true);

            var ilWriter = callMethod.GetILGenerator();

            // Load the instance if is needed
            if (mustLoadInstance)
            {
                ilWriter.Emit(OpCodes.Ldarg_0);

                if (instanceGenericConstraint != null)
                {
                    WriteCreateNewProxyInstance(ilWriter, instanceProxyType, targetType);
                }
            }

            // Load the return value
            ilWriter.Emit(OpCodes.Ldarg_1);
            if (returnValueProxyType != null)
            {
                WriteCreateNewProxyInstance(ilWriter, returnValueProxyType, returnType);
            }

            // Load the exception
            ilWriter.Emit(OpCodes.Ldarg_2);

            // Load the state
            ilWriter.Emit(OpCodes.Ldarg_3);

            // Call Method
            onMethodEndMethodInfo = onMethodEndMethodInfo.MakeGenericMethod(callGenericTypes.ToArray());
            ilWriter.EmitCall(OpCodes.Call, onMethodEndMethodInfo, null);

            // Unwrap return value proxy
            if (returnValueProxyType != null)
            {
                var unwrapReturnValue = UnwrapReturnValueMethodInfo.MakeGenericMethod(returnValueProxyType, returnType);
                ilWriter.EmitCall(OpCodes.Call, unwrapReturnValue, null);
            }

            ilWriter.Emit(OpCodes.Ret);

			Logger.Debug($"Created EndMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}, ReturnType={returnType.FullName}]");
            return callMethod;
        }

19 Source : IntegrationMapper.cs
with Apache License 2.0
from elastic

internal static CreateAsyncEndMethodResult CreateAsyncEndMethodDelegate(Type integrationType, Type targetType, Type returnType)
        {
            /*
             * OnAsyncMethodEnd signatures with 3 or 4 parameters with 1 or 2 generics:
             *      - TReturn OnAsyncMethodEnd<TTarget, TReturn>(TTarget instance, TReturn returnValue, Exception exception, CallTargetState state);
             *      - TReturn OnAsyncMethodEnd<TTarget, TReturn>(TReturn returnValue, Exception exception, CallTargetState state);
             *      - [Type] OnAsyncMethodEnd<TTarget>([Type] returnValue, Exception exception, CallTargetState state);
             *
             *      In case the continuation is for a Task/ValueTask, the returnValue type will be an object and the value null.
             *      In case the continuation is for a Task<T>/ValueTask<T>, the returnValue type will be T with the instance value after the task completes.
             *
             */

            Logger.Debug($"Creating AsyncEndMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}, ReturnType={returnType.FullName}]");
            var onAsyncMethodEndMethodInfo = integrationType.GetMethod(EndAsyncMethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
            if (onAsyncMethodEndMethodInfo is null)
            {
                Logger.Debug($"'{EndAsyncMethodName}' method was not found in integration type: '{integrationType.FullName}'.");
                return default;
            }

            if (!onAsyncMethodEndMethodInfo.ReturnType.IsGenericParameter && onAsyncMethodEndMethodInfo.ReturnType != returnType)
            {
                throw new ArgumentException($"The return type of the method: {EndAsyncMethodName} in type: {integrationType.FullName} is not {returnType}");
            }

            var genericArgumentsTypes = onAsyncMethodEndMethodInfo.GetGenericArguments();
            if (genericArgumentsTypes.Length < 1 || genericArgumentsTypes.Length > 2)
				throw new ArgumentException($"The method: {EndAsyncMethodName} in type: {integrationType.FullName} must have the generic type for the instance type.");

			var onAsyncMethodEndParameters = onAsyncMethodEndMethodInfo.GetParameters();
            if (onAsyncMethodEndParameters.Length < 3)
				throw new ArgumentException($"The method: {EndAsyncMethodName} with {onAsyncMethodEndParameters.Length} parameters in type: {integrationType.FullName} has less parameters than required.");
			else if (onAsyncMethodEndParameters.Length > 4)
				throw new ArgumentException($"The method: {EndAsyncMethodName} with {onAsyncMethodEndParameters.Length} parameters in type: {integrationType.FullName} has more parameters than required.");

			if (onAsyncMethodEndParameters[onAsyncMethodEndParameters.Length - 2].ParameterType != typeof(Exception))
				throw new ArgumentException($"The Exception type parameter of the method: {EndAsyncMethodName} in type: {integrationType.FullName} is missing.");

			if (onAsyncMethodEndParameters[onAsyncMethodEndParameters.Length - 1].ParameterType != typeof(CallTargetState))
				throw new ArgumentException($"The CallTargetState type parameter of the method: {EndAsyncMethodName} in type: {integrationType.FullName} is missing.");

			var preserveContext = onAsyncMethodEndMethodInfo.GetCustomAttribute<PreserveContextAttribute>() != null;

            var callGenericTypes = new List<Type>();

            var mustLoadInstance = onAsyncMethodEndParameters.Length == 4;
            var instanceGenericType = genericArgumentsTypes[0];
            var instanceGenericConstraint = instanceGenericType.GetGenericParameterConstraints().FirstOrDefault();
            Type instanceProxyType = null;
            if (instanceGenericConstraint != null)
            {
                var result = DuckType.GetOrCreateProxyType(instanceGenericConstraint, targetType);
                instanceProxyType = result.ProxyType;
                callGenericTypes.Add(instanceProxyType);
            }
            else
				callGenericTypes.Add(targetType);

			var returnParameterIndex = onAsyncMethodEndParameters.Length == 4 ? 1 : 0;
            var isAGenericReturnValue = onAsyncMethodEndParameters[returnParameterIndex].ParameterType.IsGenericParameter;
            Type returnValueGenericType = null;
            Type returnValueGenericConstraint = null;
            Type returnValueProxyType = null;
            if (isAGenericReturnValue)
            {
                returnValueGenericType = genericArgumentsTypes[1];
                returnValueGenericConstraint = returnValueGenericType.GetGenericParameterConstraints().FirstOrDefault();
                if (returnValueGenericConstraint != null)
                {
                    var result = DuckType.GetOrCreateProxyType(returnValueGenericConstraint, returnType);
                    returnValueProxyType = result.ProxyType;
                    callGenericTypes.Add(returnValueProxyType);
                }
                else
					callGenericTypes.Add(returnType);
			}
            else if (onAsyncMethodEndParameters[returnParameterIndex].ParameterType != returnType)
				throw new ArgumentException($"The ReturnValue type parameter of the method: {EndAsyncMethodName} in type: {integrationType.FullName} is invalid. [{onAsyncMethodEndParameters[returnParameterIndex].ParameterType} != {returnType}]");

			var callMethod = new DynamicMethod(
                     $"{onAsyncMethodEndMethodInfo.DeclaringType.Name}.{onAsyncMethodEndMethodInfo.Name}.{targetType.Name}.{returnType.Name}",
                     returnType,
                     new Type[] { targetType, returnType, typeof(Exception), typeof(CallTargetState) },
                     onAsyncMethodEndMethodInfo.Module,
                     true);

            var ilWriter = callMethod.GetILGenerator();

            // Load the instance if is needed
            if (mustLoadInstance)
            {
                ilWriter.Emit(OpCodes.Ldarg_0);

                if (instanceGenericConstraint != null)
					WriteCreateNewProxyInstance(ilWriter, instanceProxyType, targetType);
			}

            // Load the return value
            ilWriter.Emit(OpCodes.Ldarg_1);
            if (returnValueProxyType != null)
				WriteCreateNewProxyInstance(ilWriter, returnValueProxyType, returnType);

			// Load the exception
            ilWriter.Emit(OpCodes.Ldarg_2);

            // Load the state
            ilWriter.Emit(OpCodes.Ldarg_3);

            // Call Method
            onAsyncMethodEndMethodInfo = onAsyncMethodEndMethodInfo.MakeGenericMethod(callGenericTypes.ToArray());
            ilWriter.EmitCall(OpCodes.Call, onAsyncMethodEndMethodInfo, null);

            // Unwrap return value proxy
            if (returnValueProxyType != null)
            {
                var unwrapReturnValue = UnwrapReturnValueMethodInfo.MakeGenericMethod(returnValueProxyType, returnType);
                ilWriter.EmitCall(OpCodes.Call, unwrapReturnValue, null);
            }

            ilWriter.Emit(OpCodes.Ret);

            Logger.Debug($"Created AsyncEndMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}, ReturnType={returnType.FullName}]");
            return new CreateAsyncEndMethodResult(callMethod, preserveContext);
        }

19 Source : DuckType.Fields.cs
with Apache License 2.0
from elastic

private static MethodBuilder GetFieldSetMethod(TypeBuilder proxyTypeBuilder, Type targetType, MemberInfo proxyMember, FieldInfo targetField,
			FieldInfo instanceField
		)
		{
			var proxyMemberName = proxyMember.Name;
			var proxyMemberReturnType = proxyMember is PropertyInfo pinfo ? pinfo.PropertyType :
				proxyMember is FieldInfo finfo ? finfo.FieldType : typeof(object);

			var method = proxyTypeBuilder.DefineMethod(
				"set_" + proxyMemberName,
				MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig
				| MethodAttributes.Virtual,
				typeof(void),
				new[] { proxyMemberReturnType });

			var il = new LazyILGenerator(method.GetILGenerator());
			var currentValueType = proxyMemberReturnType;

			// Load instance
			if (!targetField.IsStatic)
			{
				il.Emit(OpCodes.Ldarg_0);
				il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
			}

			// Check if the type can be converted of if we need to enable duck chaining
			if (DuckType.NeedsDuckChaining(targetField.FieldType, proxyMemberReturnType))
			{
				// Load the argument and convert it to Duck type
				il.Emit(OpCodes.Ldarg_1);
				il.WriteTypeConversion(proxyMemberReturnType, typeof(IDuckType));

				// Call IDuckType.Instance property to get the actual value
				il.EmitCall(OpCodes.Callvirt, DuckTypeInstancePropertyInfo.GetMethod, null);

				currentValueType = typeof(object);
			}
			else
			{
				// Load the value into the stack
				il.Emit(OpCodes.Ldarg_1);
			}

			// We set the field value
			if (UseDirectAccessTo(proxyTypeBuilder, targetType) && targetField.IsPublic)
			{
				// If the instance and the field are public then is easy to set.
				il.WriteTypeConversion(currentValueType, targetField.FieldType);

				il.Emit(targetField.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, targetField);
			}
			else
			{
				// If the instance or the field are non public we need to create a Dynamic method to overpreplaced the visibility checks

				var dynMethodName = $"_setField_{targetField.DeclaringType.Name}_{targetField.Name}";

				// Convert the field type for the dynamic method
				var dynValueType = UseDirectAccessTo(proxyTypeBuilder, targetField.FieldType) ? targetField.FieldType : typeof(object);
				il.WriteTypeConversion(currentValueType, dynValueType);

				// Create dynamic method
				var dynParameters = targetField.IsStatic ? new[] { dynValueType } : new[] { typeof(object), dynValueType };
				var dynMethod = new DynamicMethod(dynMethodName, typeof(void), dynParameters, proxyTypeBuilder.Module, true);

				// Write the dynamic method body
				var dynIL = new LazyILGenerator(dynMethod.GetILGenerator());
				dynIL.Emit(OpCodes.Ldarg_0);

				if (targetField.IsStatic)
				{
					dynIL.WriteTypeConversion(dynValueType, targetField.FieldType);
					dynIL.Emit(OpCodes.Stsfld, targetField);
				}
				else
				{
					if (targetField.DeclaringType != typeof(object))
					{
						dynIL.Emit(OpCodes.Castclreplaced, targetField.DeclaringType);
					}

					dynIL.Emit(OpCodes.Ldarg_1);
					dynIL.WriteTypeConversion(dynValueType, targetField.FieldType);
					dynIL.Emit(OpCodes.Stfld, targetField);
				}

				dynIL.Emit(OpCodes.Ret);
				dynIL.Flush();

				// Emit the call to the dynamic method
				il.WriteDynamicMethodCall(dynMethod, proxyTypeBuilder);
			}

			il.Emit(OpCodes.Ret);
			il.Flush();
			_methodBuilderGetToken.Invoke(method, null);
			return method;
		}

19 Source : DuckType.Properties.cs
with Apache License 2.0
from elastic

private static MethodBuilder GetPropertySetMethod(TypeBuilder proxyTypeBuilder, Type targetType, MemberInfo proxyMember, PropertyInfo targetProperty, FieldInfo instanceField)
        {
            string proxyMemberName = null;
			var proxyParameterTypes = Type.EmptyTypes;
			var targetParametersTypes = GetPropertySetParametersTypes(proxyTypeBuilder, targetProperty, true).ToArray();

            if (proxyMember is PropertyInfo proxyProperty)
            {
                proxyMemberName = proxyProperty.Name;
                proxyParameterTypes = GetPropertySetParametersTypes(proxyTypeBuilder, proxyProperty, true).ToArray();
                if (proxyParameterTypes.Length != targetParametersTypes.Length)
                {
                    DuckTypePropertyArgumentsLengthException.Throw(proxyProperty);
                }
            }
            else if (proxyMember is FieldInfo proxyField)
            {
                proxyMemberName = proxyField.Name;
                proxyParameterTypes = new Type[] { proxyField.FieldType };
                if (proxyParameterTypes.Length != targetParametersTypes.Length)
                {
                    DuckTypePropertyArgumentsLengthException.Throw(targetProperty);
                }
            }

			var proxyMethod = proxyTypeBuilder.DefineMethod(
                "set_" + proxyMemberName,
                MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                typeof(void),
                proxyParameterTypes);

			var il = new LazyILGenerator(proxyMethod.GetILGenerator());
			var targetMethod = targetProperty.SetMethod;

            // Load the instance if needed
            if (!targetMethod.IsStatic)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
            }

            // Load the indexer keys and set value to the stack
            for (var pIndex = 0; pIndex < proxyParameterTypes.Length; pIndex++)
            {
				var proxyParamType = proxyParameterTypes[pIndex];
				var targetParamType = targetParametersTypes[pIndex];

                // Check if the type can be converted of if we need to enable duck chaining
                if (NeedsDuckChaining(targetParamType, proxyParamType))
                {
                    // Load the argument and cast it as Duck type
                    il.WriteLoadArgument(pIndex, false);
                    il.Emit(OpCodes.Castclreplaced, typeof(IDuckType));

                    // Call IDuckType.Instance property to get the actual value
                    il.EmitCall(OpCodes.Callvirt, DuckTypeInstancePropertyInfo.GetMethod, null);

                    targetParamType = typeof(object);
                }
                else
					il.WriteLoadArgument(pIndex, false);

				// If the target parameter type is public or if it's by ref we have to actually use the original target type.
                targetParamType = UseDirectAccessTo(proxyTypeBuilder, targetParamType) || targetParamType.IsByRef ? targetParamType : typeof(object);
                il.WriteTypeConversion(proxyParamType, targetParamType);

                targetParametersTypes[pIndex] = targetParamType;
            }

            // Call the setter method
            if (UseDirectAccessTo(proxyTypeBuilder, targetType))
            {
                // If the instance is public we can emit directly without any dynamic method

                if (targetMethod.IsPublic)
                {
                    // We can emit a normal call if we have a public instance with a public property method.
                    il.EmitCall(targetMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null);
                }
                else
                {
                    // In case we have a public instance and a non public property method we can use [Calli] with the function pointer
                    il.WriteMethodCalli(targetMethod);
                }
            }
            else
            {
                // If the instance is not public we need to create a Dynamic method to overpreplaced the visibility checks
                // we can't access non public types so we have to cast to object type (in the instance object and the return type).

				var dynMethodName = $"_setNonPublicProperty+{targetProperty.DeclaringType.Name}.{targetProperty.Name}";

                // We create the dynamic method
				var targetParameters = GetPropertySetParametersTypes(proxyTypeBuilder, targetProperty, false, !targetMethod.IsStatic).ToArray();
				var dynParameters = targetMethod.IsStatic ? targetParametersTypes : (new[] { typeof(object) }).Concat(targetParametersTypes).ToArray();
				var dynMethod = new DynamicMethod(dynMethodName, typeof(void), dynParameters, proxyTypeBuilder.Module, true);

                // Emit the dynamic method body
				var dynIL = new LazyILGenerator(dynMethod.GetILGenerator());

                if (!targetMethod.IsStatic)
                {
                    dynIL.LoadInstanceArgument(typeof(object), targetProperty.DeclaringType);
                }

                for (var idx = targetMethod.IsStatic ? 0 : 1; idx < dynParameters.Length; idx++)
                {
                    dynIL.WriteLoadArgument(idx, true);
                    dynIL.WriteTypeConversion(dynParameters[idx], targetParameters[idx]);
                }

                dynIL.EmitCall(targetMethod.IsStatic ? OpCodes.Call : OpCodes.Callvirt, targetMethod, null);
                dynIL.Emit(OpCodes.Ret);
                dynIL.Flush();

                // Create and load delegate for the DynamicMethod
                il.WriteDynamicMethodCall(dynMethod, proxyTypeBuilder);
            }

            il.Emit(OpCodes.Ret);
            il.Flush();
            _methodBuilderGetToken.Invoke(proxyMethod, null);
            return proxyMethod;
        }

19 Source : IntegrationMapper.cs
with Apache License 2.0
from elastic

internal static DynamicMethod CreateEndMethodDelegate(Type integrationType, Type targetType)
        {
            /*
             * OnMethodEnd signatures with 2 or 3 parameters with 1 generics:
             *      - CallTargetReturn OnMethodEnd<TTarget>(TTarget instance, Exception exception, CallTargetState state);
             *      - CallTargetReturn OnMethodEnd<TTarget>(Exception exception, CallTargetState state);
             *
             */

            Logger.Debug($"Creating EndMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}]");
            var onMethodEndMethodInfo = integrationType.GetMethod(EndMethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
            if (onMethodEndMethodInfo is null)
            {
                Logger.Debug($"'{EndMethodName}' method was not found in integration type: '{integrationType.FullName}'.");
                return null;
            }

            if (onMethodEndMethodInfo.ReturnType != typeof(CallTargetReturn))
				throw new ArgumentException($"The return type of the method: {EndMethodName} in type: {integrationType.FullName} is not {nameof(CallTargetReturn)}");

			var genericArgumentsTypes = onMethodEndMethodInfo.GetGenericArguments();
            if (genericArgumentsTypes.Length != 1)
				throw new ArgumentException($"The method: {EndMethodName} in type: {integrationType.FullName} must have a single generic type for the instance type.");

			var onMethodEndParameters = onMethodEndMethodInfo.GetParameters();
            if (onMethodEndParameters.Length < 2)
				throw new ArgumentException($"The method: {EndMethodName} with {onMethodEndParameters.Length} parameters in type: {integrationType.FullName} has less parameters than required.");
			else if (onMethodEndParameters.Length > 3) throw new ArgumentException($"The method: {EndMethodName} with {onMethodEndParameters.Length} parameters in type: {integrationType.FullName} has more parameters than required.");

			if (onMethodEndParameters[onMethodEndParameters.Length - 2].ParameterType != typeof(Exception))
				throw new ArgumentException($"The Exception type parameter of the method: {EndMethodName} in type: {integrationType.FullName} is missing.");

			if (onMethodEndParameters[onMethodEndParameters.Length - 1].ParameterType != typeof(CallTargetState))
				throw new ArgumentException($"The CallTargetState type parameter of the method: {EndMethodName} in type: {integrationType.FullName} is missing.");

			var callGenericTypes = new List<Type>();

            var mustLoadInstance = onMethodEndParameters.Length == 3;
            var instanceGenericType = genericArgumentsTypes[0];
            var instanceGenericConstraint = instanceGenericType.GetGenericParameterConstraints().FirstOrDefault();
            Type instanceProxyType = null;
            if (instanceGenericConstraint != null)
            {
                var result = DuckType.GetOrCreateProxyType(instanceGenericConstraint, targetType);
                instanceProxyType = result.ProxyType;
                callGenericTypes.Add(instanceProxyType);
            }
            else
				callGenericTypes.Add(targetType);

			var callMethod = new DynamicMethod(
                     $"{onMethodEndMethodInfo.DeclaringType.Name}.{onMethodEndMethodInfo.Name}",
                     typeof(CallTargetReturn),
                     new Type[] { targetType, typeof(Exception), typeof(CallTargetState) },
                     onMethodEndMethodInfo.Module,
                     true);

            var ilWriter = callMethod.GetILGenerator();

            // Load the instance if is needed
            if (mustLoadInstance)
            {
                ilWriter.Emit(OpCodes.Ldarg_0);

                if (instanceGenericConstraint != null)
					WriteCreateNewProxyInstance(ilWriter, instanceProxyType, targetType);
			}

            // Load the exception
            ilWriter.Emit(OpCodes.Ldarg_1);

            // Load the state
            ilWriter.Emit(OpCodes.Ldarg_2);

            // Call Method
            onMethodEndMethodInfo = onMethodEndMethodInfo.MakeGenericMethod(callGenericTypes.ToArray());
            ilWriter.EmitCall(OpCodes.Call, onMethodEndMethodInfo, null);

            ilWriter.Emit(OpCodes.Ret);

            Logger.Debug($"Created EndMethod Dynamic Method for '{integrationType.FullName}' integration. [Target={targetType.FullName}]");
            return callMethod;
        }

19 Source : DuckType.cs
with Apache License 2.0
from elastic

private static Delegate CreateStructCopyMethod(ModuleBuilder moduleBuilder, Type proxyDefinitionType, Type proxyType, Type targetType)
        {
			var ctor = proxyType.GetConstructors()[0];

			var createStructMethod = new DynamicMethod(
                $"CreateStructInstance<{proxyType.Name}>",
                proxyDefinitionType,
                new[] { typeof(object) },
                typeof(Elastic.Apm.Profiler.Managed.DuckTyping.DuckType).Module,
                true);
			var il = createStructMethod.GetILGenerator();

            // First we declare the locals
			var proxyLocal = il.DeclareLocal(proxyType);
			var structLocal = il.DeclareLocal(proxyDefinitionType);

            // We create an instance of the proxy type
            il.Emit(OpCodes.Ldloca_S, proxyLocal.LocalIndex);
            il.Emit(OpCodes.Ldarg_0);
            if (UseDirectAccessTo(moduleBuilder, targetType))
            {
                if (targetType.IsValueType)
                {
                    il.Emit(OpCodes.Unbox_Any, targetType);
                }
                else
                {
                    il.Emit(OpCodes.Castclreplaced, targetType);
                }
            }

            il.Emit(OpCodes.Call, ctor);

            // Create the destination structure
            il.Emit(OpCodes.Ldloca_S, structLocal.LocalIndex);
            il.Emit(OpCodes.Initobj, proxyDefinitionType);

            // Start copy properties from the proxy to the structure
            foreach (var finfo in proxyDefinitionType.GetFields())
            {
                // Skip readonly fields
                if ((finfo.Attributes & FieldAttributes.InitOnly) != 0)
                {
                    continue;
                }

                // Ignore the fields marked with `DuckIgnore` attribute
                if (finfo.GetCustomAttribute<DuckIgnoreAttribute>(true) is not null)
                {
                    continue;
                }

				var prop = proxyType.GetProperty(finfo.Name);
                il.Emit(OpCodes.Ldloca_S, structLocal.LocalIndex);
                il.Emit(OpCodes.Ldloca_S, proxyLocal.LocalIndex);
                il.EmitCall(OpCodes.Call, prop.GetMethod, null);
                il.Emit(OpCodes.Stfld, finfo);
            }

            // Return
            il.WriteLoadLocal(structLocal.LocalIndex);
            il.Emit(OpCodes.Ret);

			var delegateType = typeof(CreateProxyInstance<>).MakeGenericType(proxyDefinitionType);
            return createStructMethod.CreateDelegate(delegateType);
        }

19 Source : DuckType.Fields.cs
with Apache License 2.0
from elastic

private static MethodBuilder GetFieldGetMethod(TypeBuilder proxyTypeBuilder, Type targetType, MemberInfo proxyMember, FieldInfo targetField,
			FieldInfo instanceField
		)
		{
			var proxyMemberName = proxyMember.Name;
			var proxyMemberReturnType = proxyMember is PropertyInfo pinfo ? pinfo.PropertyType :
				proxyMember is FieldInfo finfo ? finfo.FieldType : typeof(object);

			var proxyMethod = proxyTypeBuilder.DefineMethod(
				"get_" + proxyMemberName,
				MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig
				| MethodAttributes.Virtual,
				proxyMemberReturnType,
				Type.EmptyTypes);

			var il = new LazyILGenerator(proxyMethod.GetILGenerator());
			var returnType = targetField.FieldType;

			// Load the instance
			if (!targetField.IsStatic)
			{
				il.Emit(OpCodes.Ldarg_0);
				il.Emit(instanceField.FieldType.IsValueType ? OpCodes.Ldflda : OpCodes.Ldfld, instanceField);
			}

			// Load the field value to the stack
			if (UseDirectAccessTo(proxyTypeBuilder, targetType) && targetField.IsPublic)
			{
				// In case is public is pretty simple
				il.Emit(targetField.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, targetField);
			}
			else
			{
				// If the instance or the field are non public we need to create a Dynamic method to overpreplaced the visibility checks
				// we can't access non public types so we have to cast to object type (in the instance object and the return type if is needed).
				var dynMethodName = $"_getNonPublicField_{targetField.DeclaringType.Name}_{targetField.Name}";
				returnType = UseDirectAccessTo(proxyTypeBuilder, targetField.FieldType) ? targetField.FieldType : typeof(object);

				// We create the dynamic method
				var dynParameters = targetField.IsStatic ? Type.EmptyTypes : new[] { typeof(object) };
				var dynMethod = new DynamicMethod(dynMethodName, returnType, dynParameters, proxyTypeBuilder.Module, true);

				// Emit the dynamic method body
				var dynIL = new LazyILGenerator(dynMethod.GetILGenerator());

				if (!targetField.IsStatic)
				{
					// Emit the instance load in the dynamic method
					dynIL.Emit(OpCodes.Ldarg_0);
					if (targetField.DeclaringType != typeof(object))
					{
						dynIL.Emit(targetField.DeclaringType!.IsValueType ? OpCodes.Unbox : OpCodes.Castclreplaced, targetField.DeclaringType);
					}
				}

				// Emit the field and convert before returning (in case of boxing)
				dynIL.Emit(targetField.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, targetField);
				dynIL.WriteTypeConversion(targetField.FieldType, returnType);
				dynIL.Emit(OpCodes.Ret);
				dynIL.Flush();

				// Emit the call to the dynamic method
				il.WriteDynamicMethodCall(dynMethod, proxyTypeBuilder);
			}

			// Check if the type can be converted or if we need to enable duck chaining
			if (DuckType.NeedsDuckChaining(targetField.FieldType, proxyMemberReturnType))
			{
				if (UseDirectAccessTo(proxyTypeBuilder, targetField.FieldType) && targetField.FieldType.IsValueType)
				{
					il.Emit(OpCodes.Box, targetField.FieldType);
				}

				// We call DuckType.CreateCache<>.Create()
				var getProxyMethodInfo = typeof(DuckType.CreateCache<>)
					.MakeGenericType(proxyMemberReturnType)
					.GetMethod("Create");

				il.Emit(OpCodes.Call, getProxyMethodInfo);
			}
			else if (returnType != proxyMemberReturnType)
			{
				// If the type is not the expected type we try a conversion.
				il.WriteTypeConversion(returnType, proxyMemberReturnType);
			}

			il.Emit(OpCodes.Ret);
			il.Flush();
			_methodBuilderGetToken.Invoke(proxyMethod, null);
			return proxyMethod;
		}

19 Source : DuckType.cs
with Apache License 2.0
from elastic

private static Delegate GetCreateProxyInstanceDelegate(ModuleBuilder moduleBuilder, Type proxyDefinitionType, Type proxyType, Type targetType)
        {
			var ctor = proxyType.GetConstructors()[0];

			var createProxyMethod = new DynamicMethod(
                $"CreateProxyInstance<{proxyType.Name}>",
                proxyDefinitionType,
                new[] { typeof(object) },
                typeof(DuckType).Module,
                true);
			var il = createProxyMethod.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            if (UseDirectAccessTo(moduleBuilder, targetType))
            {
                if (targetType.IsValueType)
                {
                    il.Emit(OpCodes.Unbox_Any, targetType);
                }
                else
                {
                    il.Emit(OpCodes.Castclreplaced, targetType);
                }
            }

            il.Emit(OpCodes.Newobj, ctor);

            if (proxyType.IsValueType)
            {
                il.Emit(OpCodes.Box, proxyType);
            }

            il.Emit(OpCodes.Ret);
			var delegateType = typeof(CreateProxyInstance<>).MakeGenericType(proxyDefinitionType);
            return createProxyMethod.CreateDelegate(delegateType);
        }

See More Examples