| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
- using System.Reflection.Emit;
- namespace ARMeilleure.Translation
- {
- static class DelegateHelper
- {
- private const string DelegateTypesAssemblyName = "JitDelegateTypes";
- private static readonly ModuleBuilder _modBuilder;
- private static readonly Dictionary<string, Type> _delegateTypesCache;
- static DelegateHelper()
- {
- AssemblyBuilder asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(DelegateTypesAssemblyName), AssemblyBuilderAccess.Run);
- _modBuilder = asmBuilder.DefineDynamicModule(DelegateTypesAssemblyName);
- _delegateTypesCache = new Dictionary<string, Type>();
- }
- public static Delegate GetDelegate(MethodInfo info)
- {
- ArgumentNullException.ThrowIfNull(info);
- Type[] parameters = info.GetParameters().Select(pI => pI.ParameterType).ToArray();
- Type returnType = info.ReturnType;
- Type delegateType = GetDelegateType(parameters, returnType);
- return Delegate.CreateDelegate(delegateType, info);
- }
- private static Type GetDelegateType(Type[] parameters, Type returnType)
- {
- string key = GetFunctionSignatureKey(parameters, returnType);
- if (!_delegateTypesCache.TryGetValue(key, out Type delegateType))
- {
- delegateType = MakeDelegateType(parameters, returnType, key);
- _delegateTypesCache.TryAdd(key, delegateType);
- }
- return delegateType;
- }
- private static string GetFunctionSignatureKey(Type[] parameters, Type returnType)
- {
- string sig = GetTypeName(returnType);
- foreach (Type type in parameters)
- {
- sig += '_' + GetTypeName(type);
- }
- return sig;
- }
- private static string GetTypeName(Type type)
- {
- return type.FullName.Replace(".", string.Empty);
- }
- private const MethodAttributes CtorAttributes =
- MethodAttributes.RTSpecialName |
- MethodAttributes.HideBySig |
- MethodAttributes.Public;
- private const TypeAttributes DelegateTypeAttributes =
- TypeAttributes.Class |
- TypeAttributes.Public |
- TypeAttributes.Sealed |
- TypeAttributes.AnsiClass |
- TypeAttributes.AutoClass;
- private const MethodImplAttributes ImplAttributes =
- MethodImplAttributes.Runtime |
- MethodImplAttributes.Managed;
- private const MethodAttributes InvokeAttributes =
- MethodAttributes.Public |
- MethodAttributes.HideBySig |
- MethodAttributes.NewSlot |
- MethodAttributes.Virtual;
- private static readonly Type[] _delegateCtorSignature = { typeof(object), typeof(IntPtr) };
- private static Type MakeDelegateType(Type[] parameters, Type returnType, string name)
- {
- TypeBuilder builder = _modBuilder.DefineType(name, DelegateTypeAttributes, typeof(MulticastDelegate));
- builder.DefineConstructor(CtorAttributes, CallingConventions.Standard, _delegateCtorSignature).SetImplementationFlags(ImplAttributes);
- builder.DefineMethod("Invoke", InvokeAttributes, returnType, parameters).SetImplementationFlags(ImplAttributes);
- return builder.CreateTypeInfo();
- }
- }
- }
|