Mercurial > pub > bltoolkit
view Extensions/JointureAddOn/Emit/DynamicCompilationSpike.cs @ 3:1ef98bd70424
!bug 100 +3h
Исправление проблемы BLToolkit + mono 3.4
author | cin |
---|---|
date | Fri, 22 Aug 2014 17:34:46 +0400 |
parents | f990fcb411a9 |
children |
line wrap: on
line source
using System; using System.Reflection; using System.Reflection.Emit; namespace BLToolkit.Emit { public delegate object GetHandler(object source); public delegate void SetHandler(object source, object value); public delegate object InstantiateObjectHandler(); public static class DynamicMethodCompiler { // DynamicMethodCompiler // CreateInstantiateObjectDelegate internal static InstantiateObjectHandler CreateInstantiateObjectHandler(Type type) { ConstructorInfo constructorInfo = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null); if (constructorInfo == null) { throw new ApplicationException( string.Format( "The type {0} must declare an empty constructor (the constructor may be private, internal, protected, protected internal, or public).", type)); } var dynamicMethod = new DynamicMethod("InstantiateObject", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, typeof(object), null, type, true); ILGenerator generator = dynamicMethod.GetILGenerator(); generator.Emit(OpCodes.Newobj, constructorInfo); generator.Emit(OpCodes.Ret); return (InstantiateObjectHandler)dynamicMethod.CreateDelegate(typeof(InstantiateObjectHandler)); } // CreateGetDelegate internal static GetHandler CreateGetHandler(Type type, PropertyInfo propertyInfo) { MethodInfo getMethodInfo = propertyInfo.GetGetMethod(true); DynamicMethod dynamicGet = CreateGetDynamicMethod(type); ILGenerator getGenerator = dynamicGet.GetILGenerator(); getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Call, getMethodInfo); BoxIfNeeded(getMethodInfo.ReturnType, getGenerator); getGenerator.Emit(OpCodes.Ret); return (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler)); } // CreateGetDelegate internal static GetHandler CreateGetHandler(Type type, FieldInfo fieldInfo) { DynamicMethod dynamicGet = CreateGetDynamicMethod(type); ILGenerator getGenerator = dynamicGet.GetILGenerator(); getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Ldfld, fieldInfo); BoxIfNeeded(fieldInfo.FieldType, getGenerator); getGenerator.Emit(OpCodes.Ret); return (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler)); } // CreateSetDelegate internal static SetHandler CreateSetHandler(Type type, PropertyInfo propertyInfo) { MethodInfo setMethodInfo = propertyInfo.GetSetMethod(true); DynamicMethod dynamicSet = CreateSetDynamicMethod(type); ILGenerator setGenerator = dynamicSet.GetILGenerator(); setGenerator.Emit(OpCodes.Ldarg_0); setGenerator.Emit(OpCodes.Ldarg_1); UnboxIfNeeded(setMethodInfo.GetParameters()[0].ParameterType, setGenerator); setGenerator.Emit(OpCodes.Call, setMethodInfo); setGenerator.Emit(OpCodes.Ret); return (SetHandler)dynamicSet.CreateDelegate(typeof(SetHandler)); } // CreateSetDelegate internal static SetHandler CreateSetHandler(Type type, FieldInfo fieldInfo) { DynamicMethod dynamicSet = CreateSetDynamicMethod(type); ILGenerator setGenerator = dynamicSet.GetILGenerator(); setGenerator.Emit(OpCodes.Ldarg_0); setGenerator.Emit(OpCodes.Ldarg_1); UnboxIfNeeded(fieldInfo.FieldType, setGenerator); setGenerator.Emit(OpCodes.Stfld, fieldInfo); setGenerator.Emit(OpCodes.Ret); return (SetHandler)dynamicSet.CreateDelegate(typeof(SetHandler)); } // CreateGetDynamicMethod private static DynamicMethod CreateGetDynamicMethod(Type type) { return new DynamicMethod("DynamicGet", typeof(object), new[] { typeof(object) }, type, true); } // CreateSetDynamicMethod private static DynamicMethod CreateSetDynamicMethod(Type type) { return new DynamicMethod("DynamicSet", typeof(void), new[] { typeof(object), typeof(object) }, type, true); } // BoxIfNeeded private static void BoxIfNeeded(Type type, ILGenerator generator) { if (type.IsValueType) { generator.Emit(OpCodes.Box, type); } } // UnboxIfNeeded private static void UnboxIfNeeded(Type type, ILGenerator generator) { if (type.IsValueType) { generator.Emit(OpCodes.Unbox_Any, type); } } } }