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
19
Source : Mem.cs
with GNU General Public License v3.0
from Decimation
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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