Mercurial > pub > bltoolkit
comparison Extensions/JointureAddOn/Emit/DynamicCompilationSpike.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f990fcb411a9 |
---|---|
1 using System; | |
2 using System.Reflection; | |
3 using System.Reflection.Emit; | |
4 | |
5 namespace BLToolkit.Emit | |
6 { | |
7 public delegate object GetHandler(object source); | |
8 | |
9 public delegate void SetHandler(object source, object value); | |
10 | |
11 public delegate object InstantiateObjectHandler(); | |
12 | |
13 public static class DynamicMethodCompiler | |
14 { | |
15 // DynamicMethodCompiler | |
16 | |
17 // CreateInstantiateObjectDelegate | |
18 internal static InstantiateObjectHandler CreateInstantiateObjectHandler(Type type) | |
19 { | |
20 ConstructorInfo constructorInfo = | |
21 type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, | |
22 new Type[0], null); | |
23 if (constructorInfo == null) | |
24 { | |
25 throw new ApplicationException( | |
26 string.Format( | |
27 "The type {0} must declare an empty constructor (the constructor may be private, internal, protected, protected internal, or public).", | |
28 type)); | |
29 } | |
30 | |
31 var dynamicMethod = new DynamicMethod("InstantiateObject", MethodAttributes.Static | MethodAttributes.Public, | |
32 CallingConventions.Standard, typeof(object), null, type, true); | |
33 ILGenerator generator = dynamicMethod.GetILGenerator(); | |
34 generator.Emit(OpCodes.Newobj, constructorInfo); | |
35 generator.Emit(OpCodes.Ret); | |
36 return (InstantiateObjectHandler)dynamicMethod.CreateDelegate(typeof(InstantiateObjectHandler)); | |
37 } | |
38 | |
39 // CreateGetDelegate | |
40 internal static GetHandler CreateGetHandler(Type type, PropertyInfo propertyInfo) | |
41 { | |
42 MethodInfo getMethodInfo = propertyInfo.GetGetMethod(true); | |
43 DynamicMethod dynamicGet = CreateGetDynamicMethod(type); | |
44 ILGenerator getGenerator = dynamicGet.GetILGenerator(); | |
45 | |
46 getGenerator.Emit(OpCodes.Ldarg_0); | |
47 getGenerator.Emit(OpCodes.Call, getMethodInfo); | |
48 BoxIfNeeded(getMethodInfo.ReturnType, getGenerator); | |
49 getGenerator.Emit(OpCodes.Ret); | |
50 | |
51 return (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler)); | |
52 } | |
53 | |
54 // CreateGetDelegate | |
55 internal static GetHandler CreateGetHandler(Type type, FieldInfo fieldInfo) | |
56 { | |
57 DynamicMethod dynamicGet = CreateGetDynamicMethod(type); | |
58 ILGenerator getGenerator = dynamicGet.GetILGenerator(); | |
59 | |
60 getGenerator.Emit(OpCodes.Ldarg_0); | |
61 getGenerator.Emit(OpCodes.Ldfld, fieldInfo); | |
62 BoxIfNeeded(fieldInfo.FieldType, getGenerator); | |
63 getGenerator.Emit(OpCodes.Ret); | |
64 | |
65 return (GetHandler)dynamicGet.CreateDelegate(typeof(GetHandler)); | |
66 } | |
67 | |
68 // CreateSetDelegate | |
69 internal static SetHandler CreateSetHandler(Type type, PropertyInfo propertyInfo) | |
70 { | |
71 MethodInfo setMethodInfo = propertyInfo.GetSetMethod(true); | |
72 DynamicMethod dynamicSet = CreateSetDynamicMethod(type); | |
73 ILGenerator setGenerator = dynamicSet.GetILGenerator(); | |
74 | |
75 setGenerator.Emit(OpCodes.Ldarg_0); | |
76 setGenerator.Emit(OpCodes.Ldarg_1); | |
77 UnboxIfNeeded(setMethodInfo.GetParameters()[0].ParameterType, setGenerator); | |
78 setGenerator.Emit(OpCodes.Call, setMethodInfo); | |
79 setGenerator.Emit(OpCodes.Ret); | |
80 | |
81 return (SetHandler)dynamicSet.CreateDelegate(typeof(SetHandler)); | |
82 } | |
83 | |
84 // CreateSetDelegate | |
85 internal static SetHandler CreateSetHandler(Type type, FieldInfo fieldInfo) | |
86 { | |
87 DynamicMethod dynamicSet = CreateSetDynamicMethod(type); | |
88 ILGenerator setGenerator = dynamicSet.GetILGenerator(); | |
89 | |
90 setGenerator.Emit(OpCodes.Ldarg_0); | |
91 setGenerator.Emit(OpCodes.Ldarg_1); | |
92 UnboxIfNeeded(fieldInfo.FieldType, setGenerator); | |
93 setGenerator.Emit(OpCodes.Stfld, fieldInfo); | |
94 setGenerator.Emit(OpCodes.Ret); | |
95 | |
96 return (SetHandler)dynamicSet.CreateDelegate(typeof(SetHandler)); | |
97 } | |
98 | |
99 // CreateGetDynamicMethod | |
100 private static DynamicMethod CreateGetDynamicMethod(Type type) | |
101 { | |
102 return new DynamicMethod("DynamicGet", typeof(object), new[] { typeof(object) }, type, true); | |
103 } | |
104 | |
105 // CreateSetDynamicMethod | |
106 private static DynamicMethod CreateSetDynamicMethod(Type type) | |
107 { | |
108 return new DynamicMethod("DynamicSet", typeof(void), new[] { typeof(object), typeof(object) }, type, true); | |
109 } | |
110 | |
111 // BoxIfNeeded | |
112 private static void BoxIfNeeded(Type type, ILGenerator generator) | |
113 { | |
114 if (type.IsValueType) | |
115 { | |
116 generator.Emit(OpCodes.Box, type); | |
117 } | |
118 } | |
119 | |
120 // UnboxIfNeeded | |
121 private static void UnboxIfNeeded(Type type, ILGenerator generator) | |
122 { | |
123 if (type.IsValueType) | |
124 { | |
125 generator.Emit(OpCodes.Unbox_Any, type); | |
126 } | |
127 } | |
128 } | |
129 } |