Nbear讲解 之核心类CodeGenerator

以下是CodeGenerator类用的一些辅助类:
Cmp比较类型
 1  /// <summary>
 2     /// Cmp
 3     /// </summary>
 4     public enum Cmp
 5     {
 6         /// <summary>
 7         /// LessThan
 8         /// </summary>
 9         LessThan,
10         /// <summary>
11         /// EqualTo
12         /// </summary>
13         EqualTo,
14         /// <summary>
15         /// LessThanOrEqualTo
16         /// </summary>
17         LessThanOrEqualTo,
18         /// <summary>
19         /// GreaterThan
20         /// </summary>
21         GreaterThan,
22         /// <summary>
23         /// NotEqualTo
24         /// </summary>
25         NotEqualTo,
26         /// <summary>
27         /// GreaterThanOrEqualTo
28         /// </summary>
29         GreaterThanOrEqualTo
30     }
ArgBuilder方法参数定义
 1    /// <summary>
 2     /// ArgBuilder
 3     /// </summary>
 4     public class ArgBuilder
 5     {
 6         /// <summary>
 7         /// ArgType
 8         /// </summary>
 9         public Type ArgType;
10         /// <summary>
11         /// Index
12         /// </summary>
13         public int Index;
14 
15         /// <summary>
16         /// ArgBuilder
17         /// </summary>
18         /// <param name="index"></param>
19         /// <param name="argType"></param>
20         public ArgBuilder(int index, Type argType)
21         {
22             this.Index = index;
23             this.ArgType = argType;
24         }
25     }
IfState[If语句之状态]
 1   /// <summary>
 2     /// IfState
 3     /// </summary>
 4     public class IfState
 5     {
 6         // Fields
 7         private Label elseBegin;
 8         private Label endIf;
 9 
10         /// <summary>
11         /// ElseBegin
12         /// </summary>
13         public Label ElseBegin
14         {
15             get
16             {
17                 return this.elseBegin;
18             }
19             set
20             {
21                 this.elseBegin = value;
22             }
23         }
24 
25         /// <summary>
26         /// EndIf
27         /// </summary>
28         public Label EndIf
29         {
30             get
31             {
32                 return this.endIf;
33             }
34             set
35             {
36                 this.endIf = value;
37             }
38         }
39     }
SwitchState[Switch语句之状态]
 1   /// <summary>
 2     /// SwitchState
 3     /// </summary>
 4     public class SwitchState
 5     {
 6         private bool defaultDefined;
 7         private Label defaultLabel;
 8         private Label endOfSwitchLabel;
 9 
10         /// <summary>
11         /// SwitchState
12         /// </summary>
13         /// <param name="defaultLabel"></param>
14         /// <param name="endOfSwitchLabel"></param>
15         public SwitchState(Label defaultLabel, Label endOfSwitchLabel)
16         {
17             this.defaultLabel = defaultLabel;
18             this.endOfSwitchLabel = endOfSwitchLabel;
19             this.defaultDefined = false;
20         }
21 
22         /// <summary>
23         /// DefaultDefined
24         /// </summary>
25         public bool DefaultDefined
26         {
27             get
28             {
29                 return this.defaultDefined;
30             }
31             set
32             {
33                 this.defaultDefined = value;
34             }
35         }
36 
37         /// <summary>
38         /// DefaultLabel
39         /// </summary>
40         public Label DefaultLabel
41         {
42             get
43             {
44                 return this.defaultLabel;
45             }
46         }
47 
48         /// <summary>
49         /// EndOfSwitchLabel
50         /// </summary>
51         public Label EndOfSwitchLabel
52         {
53             get
54             {
55                 return this.endOfSwitchLabel;
56             }
57         }
58     }
ForState[For语句之状态]
  1    /// <summary>
  2     /// ForState
  3     /// </summary>
  4     public class ForState
  5     {
  6         // Fields
  7         private Label beginLabel;
  8         private object end;
  9         private Label endLabel;
 10         private LocalBuilder indexVar;
 11         private bool requiresEndLabel;
 12         private Label testLabel;
 13 
 14         /// <summary>
 15         /// ForState
 16         /// </summary>
 17         /// <param name="indexVar"></param>
 18         /// <param name="beginLabel"></param>
 19         /// <param name="testLabel"></param>
 20         /// <param name="end"></param>
 21         public ForState(LocalBuilder indexVar, Label beginLabel, Label testLabel, object end)
 22         {
 23             this.indexVar = indexVar;
 24             this.beginLabel = beginLabel;
 25             this.testLabel = testLabel;
 26             this.end = end;
 27         }
 28 
 29         /// <summary>
 30         /// BeginLabel
 31         /// </summary>
 32         public Label BeginLabel
 33         {
 34             get
 35             {
 36                 return this.beginLabel;
 37             }
 38         }
 39 
 40         /// <summary>
 41         /// End
 42         /// </summary>
 43         public object End
 44         {
 45             get
 46             {
 47                 return this.end;
 48             }
 49         }
 50 
 51         /// <summary>
 52         /// EndLabel
 53         /// </summary>
 54         public Label EndLabel
 55         {
 56             get
 57             {
 58                 return this.endLabel;
 59             }
 60             set
 61             {
 62                 this.endLabel = value;
 63             }
 64         }
 65         
 66         /// <summary>
 67         /// Index
 68         /// </summary>
 69         public LocalBuilder Index
 70         {
 71             get
 72             {
 73                 return this.indexVar;
 74             }
 75         }
 76 
 77         /// <summary>
 78         /// RequiresEndLabel
 79         /// </summary>
 80         public bool RequiresEndLabel
 81         {
 82             get
 83             {
 84                 return this.requiresEndLabel;
 85             }
 86             set
 87             {
 88                 this.requiresEndLabel = value;
 89             }
 90         }
 91 
 92         /// <summary>
 93         /// TestLabel
 94         /// </summary>
 95         public Label TestLabel
 96         {
 97             get
 98             {
 99                 return this.testLabel;
100             }
101         }
102     }

  介绍一下 ILGenerator

         其主要功能是:将指定的指令放到指令流上,构建方法体所用。
         用于为动态程序集中的方法和构造函数(由 MethodBuilder 和 ConstructorBuilder 类表示)以及为独立动态方法(由 DynamicMethod 类表示)生成方法体。
         若要获取 ILGenerator,请使用 ConstructorBuilder.GetILGenerator、DynamicMethod.GetILGenerator 和 MethodBuilder.GetILGenerator 方法。

字段主要分:方法体的环境变量,常用工具方法的MethodInfo

字段定义
 1  private ILGenerator ilGen;
 2         private Module serializationModule = typeof(CodeGenerator).Module;         
 3        
 4 
 5         //构建方法体主要的环境变量
 6         private Type delegateType;
 7         private DynamicMethod dynamicMethod; //当前类是通过委托,构建动态方法时用到
 8         private MethodBase methodOrConstructorBuilder; //当前类使用第3个构造方法时用到
 9         private Stack blockStack;
10         private ArrayList argList;
11         private Hashtable localNames;
12         private LocalBuilder stringFormatArray;
13         private Label methodEndLabel;        
14 
15          //常用工具方法
16         private static MethodInfo getTypeFromHandle;
17         private static MethodInfo objectEquals;
18         private static MethodInfo objectToString;     
19         private static MethodInfo stringConcat2;
20         private static MethodInfo stringConcat3;
21         private static MethodInfo stringFormat;
常量加载
  1    /// <summary>
  2         /// Ldc 通过Ldc指令加载布尔值到计算堆栈 true 为 1,false 为0        
  3         /// </summary>
  4         /// <param name="boolVar"></param>
  5         public void Ldc(bool boolVar)
  6         {
  7             if (boolVar)
  8             {
  9                 this.ilGen.Emit(OpCodes.Ldc_I4_1);
 10             }
 11             else
 12             {
 13                 this.ilGen.Emit(OpCodes.Ldc_I4_0);
 14             }
 15         }
 16 
 17 
 18 
 19         /// <summary>
 20         /// Ldc 加载整型数值到计算堆栈
 21         /// <list type="">
 22         /// ldc.i4.m1 (ldc.i4.M1)    -1 
 23         /// ldc.i4.0                0
 24         /// ...
 25         /// ldc.i4.8                8
 26         /// Ldc_I4                  普通整数
 27         /// </list>
 28         /// </summary>
 29         /// <param name="intVar"></param>
 30         public void Ldc(int intVar)
 31         {
 32             switch (intVar)
 33             {
 34                 case -1:
 35                     this.ilGen.Emit(OpCodes.Ldc_I4_M1);
 36                     return;
 37 
 38                 case 0:
 39                     this.ilGen.Emit(OpCodes.Ldc_I4_0);
 40                     return;
 41 
 42                 case 1:
 43                     this.ilGen.Emit(OpCodes.Ldc_I4_1);
 44                     return;
 45 
 46                 case 2:
 47                     this.ilGen.Emit(OpCodes.Ldc_I4_2);
 48                     return;
 49 
 50                 case 3:
 51                     this.ilGen.Emit(OpCodes.Ldc_I4_3);
 52                     return;
 53 
 54                 case 4:
 55                     this.ilGen.Emit(OpCodes.Ldc_I4_4);
 56                     return;
 57 
 58                 case 5:
 59                     this.ilGen.Emit(OpCodes.Ldc_I4_5);
 60                     return;
 61 
 62                 case 6:
 63                     this.ilGen.Emit(OpCodes.Ldc_I4_6);
 64                     return;
 65 
 66                 case 7:
 67                     this.ilGen.Emit(OpCodes.Ldc_I4_7);
 68                     return;
 69 
 70                 case 8:
 71                     this.ilGen.Emit(OpCodes.Ldc_I4_8);
 72                     return;
 73             }
 74             this.ilGen.Emit(OpCodes.Ldc_I4, intVar);
 75         }
 76 
 77         /// <summary>
 78         /// Ldc 加载长整数到计算堆栈   对应指令 ldc.i8 
 79         /// </summary>
 80         /// <param name="l">The l.</param>
 81         public void Ldc(long l)
 82         {
 83             this.ilGen.Emit(OpCodes.Ldc_I8, l);
 84         }
 85 
 86         /// <summary>
 87         /// Ldc 加载单精度浮点数到计算堆栈
 88         /// </summary>
 89         /// <param name="f"></param>
 90         public void Ldc(float f)
 91         {
 92             this.ilGen.Emit(OpCodes.Ldc_R4, f);
 93         }
 94 
 95         /// <summary>
 96         /// Ldc 加载双精度浮点数到计算堆栈 对应指令:Ldc_R8
 97         /// </summary>
 98         /// <param name="d"></param>
 99         public void Ldc(double d)
100         {
101             this.ilGen.Emit(OpCodes.Ldc_R8, d);
102         }
103 
104         /// <summary>
105         /// Ldc 传入一个未知类型对象,根据其类型,自动调用适合的指令来将它加载到计算堆栈
106         /// </summary>
107         /// <param name="o"></param>
108         public void Ldc(object o)
109         {
110             Type enumType = o.GetType();
111             if (o is Type)//类型变量
112             {
113                 //相当于  typeof(o);
114                 this.Ldtoken((Type)o);
115                 this.Call(GetTypeFromHandle);
116             }
117             else if (enumType.IsEnum)
118             {
119                 //Enum.GetUnderlyingType(enumType):返回指定的枚举的基础类型,即枚举定义类型
120                 //枚举类型转为 数值类型
121                 this.Ldc(((IConvertible)o).ToType(Enum.GetUnderlyingType(enumType), null));
122             }
123             else
124             {
125                 switch (Type.GetTypeCode(enumType))
126                 {
127                     case TypeCode.Boolean:
128                         this.Ldc((bool)o);
129                         return;
130 
131                     case TypeCode.Char:
132                     //throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString("CharIsInvalidPrimitive")));
133 
134                     case TypeCode.SByte:
135                     case TypeCode.Byte:
136                     case TypeCode.Int16:
137                     case TypeCode.UInt16:
138                         this.Ldc(((IConvertible)o).ToInt32(CultureInfo.InvariantCulture));
139                         return;
140 
141                     case TypeCode.Int32:
142                         this.Ldc((int)o);
143                         return;
144 
145                     case TypeCode.UInt32:
146                         this.Ldc((int)((uint)o));
147                         return;
148 
149                     case TypeCode.Int64:
150                         this.Ldc((long)o);
151                         return;
152 
153                     case TypeCode.UInt64:
154                         this.Ldc((long)((ulong)o));
155                         return;
156 
157                     case TypeCode.Single:
158                         this.Ldc((float)o);
159                         return;
160 
161                     case TypeCode.Double:
162                         this.Ldc((double)o);
163                         return;
164 
165                     case TypeCode.String:
166                         this.Ldstr((string)o);
167                         return;
168                 }
169                 throw new Exception("UnknownConstantType");
170             }
171         }
局部变量定义
 1     /// <summary>
 2         /// DeclareLocal
 3         /// </summary>
 4         /// <param name="type"></param>
 5         /// <returns></returns>
 6         public LocalBuilder DeclareLocal(Type type)
 7         {
 8             Check.Require(type, "type");
 9 
10             return this.DeclareLocal(type, null, false);
11         }
12 
13         /// <summary>
14         /// DeclareLocal
15         /// </summary>
16         /// <param name="type"></param>
17         /// <param name="name"></param>
18         /// <returns></returns>
19         public LocalBuilder DeclareLocal(Type type, string name)
20         {
21             Check.Require(type, "type");
22 
23             return this.DeclareLocal(type, name, false);
24         }
25 
26         /// <summary>
27         /// DeclareLocal
28         /// </summary>
29         /// <param name="type"></param>
30         /// <param name="name"></param>
31         /// <param name="isPinned"></param>
32         /// <returns></returns>
33         public LocalBuilder DeclareLocal(Type type, string name, bool isPinned)
34         {
35             Check.Require(type, "type");
36 
37             LocalBuilder builder = this.ilGen.DeclareLocal(type, isPinned);
38             return builder;
39         }
40 
41         /// <summary>
42         /// DeclareLocal
43         /// </summary>
44         /// <param name="type"></param>
45         /// <param name="name"></param>
46         /// <param name="initialValue"></param>
47         /// <returns></returns>
48         public LocalBuilder DeclareLocal(Type type, string name, object initialValue)
49         {
50             Check.Require(type, "type");
51 
52             LocalBuilder var = this.DeclareLocal(type, name);
53             this.Load(initialValue);
54             this.Store(var);
55             return var;
56         }

 变量:局部变量,参数变量,常量,静态变量。 分类:值类型,引用类型(属性值,数组)

变量存储
  1 /// <summary>
  2         /// Set:
  3         /// </summary>
  4         /// <param name="local"></param>
  5         /// <param name="value"></param>
  6         public void Set(LocalBuilder local, object value)
  7         {
  8             Check.Require(local, "local");
  9 
 10             this.Load(value);
 11             this.Store(local);
 12         }
 13 
 14         /// <summary>
 15         /// Starg
 16         /// </summary>
 17         /// <param name="slot"></param>
 18         public void Starg(int slot)
 19         {
 20             if (slot <= 0xff)
 21             {
 22                 this.ilGen.Emit(OpCodes.Starg_S, slot);
 23             }
 24             else
 25             {
 26                 this.ilGen.Emit(OpCodes.Starg, slot);
 27             }
 28         }
 29 
 30         /// <summary>
 31         /// Starg
 32         /// </summary>
 33         /// <param name="arg"></param>
 34         public void Starg(ArgBuilder arg)
 35         {
 36             Check.Require(arg, "arg");
 37 
 38             this.Starg(arg.Index);
 39         }
 40 
 41         /// <summary> 9
 42         /// Stelem
 43         /// </summary>
 44         /// <param name="arrayElementType"></param>
 45         public void Stelem(Type arrayElementType)
 46         {
 47             Check.Require(arrayElementType, "arrayElementType");
 48 
 49             if (arrayElementType.IsEnum)
 50             {
 51                 this.Stelem(Enum.GetUnderlyingType(arrayElementType));
 52             }
 53             else
 54             {
 55                 OpCode opcode = this.GetStelemOpCode(Type.GetTypeCode(arrayElementType));
 56                 if (opcode.Equals(OpCodes.Nop))
 57                 {
 58                     throw new Exception("ArrayTypeIsNotSupported");
 59                 }
 60                 this.ilGen.Emit(opcode);
 61             }
 62         }
 63 
 64         /// <summary>
 65         /// Stloc: 从计算堆栈的顶部弹出当前值并将其存储到指定索引处的局部变量列表中。
 66         /// </summary>
 67         /// <param name="slot"></param>
 68         public void Stloc(int slot)
 69         {
 70             switch (slot)
 71             {
 72                 case 0:
 73                     this.ilGen.Emit(OpCodes.Stloc_0);
 74                     return;
 75 
 76                 case 1:
 77                     this.ilGen.Emit(OpCodes.Stloc_1);
 78                     return;
 79 
 80                 case 2:
 81                     this.ilGen.Emit(OpCodes.Stloc_2);
 82                     return;
 83 
 84                 case 3:
 85                     this.ilGen.Emit(OpCodes.Stloc_3);
 86                     return;
 87             }
 88             if (slot <= 0xff)
 89             {
 90                 this.ilGen.Emit(OpCodes.Stloc_S, slot);
 91             }
 92             else
 93             {
 94                 this.ilGen.Emit(OpCodes.Stloc, slot);
 95             }
 96         }
 97 
 98         /// <summary>
 99         /// Stloc:从计算堆栈的顶部弹出当前值并将其存储到指定索引处的局部变量列表中。
100         ///  提示:LocalBuilder对象包含局部变量的索引跟类型
101         /// </summary>
102         /// <param name="local"></param>
103         public void Stloc(LocalBuilder local)
104         {
105             Check.Require(local, "local");
106 
107             this.ilGen.Emit(OpCodes.Stloc, local);
108         }
109 
110         /// <summary>
111         /// Stobj:将指定类型的值从计算堆栈复制到所提供的内存地址中。
112         ///    Pre1:   将地址推送到堆栈上。
113         ///    Pre2:   将 class 类型的值类型对象推送到堆栈上。
114         ///    TODO:   从堆栈中弹出对象和地址;将值类型对象存储在该地址。    
115         ///    参考:    http://msdn.microsoft.com/zh-cn/library/system.reflection.emit.opcodes.stobj.aspx
116         /// </summary>
117         /// <param name="type"></param>
118         public void Stobj(Type type)
119         {
120             Check.Require(type, "type");
121 
122             this.ilGen.Emit(OpCodes.Stobj, type);
123         }
124 
125         /// <summary>
126         /// Store:保存参数变量或局部变量
127         /// </summary>
128         /// <param name="var"></param>
129         public void Store(object var)
130         {
131             if (var is ArgBuilder)
132             {
133                 this.Starg((ArgBuilder)var);
134             }
135             else
136             {
137                 if (!(var is LocalBuilder))
138                 {
139                     throw new Exception("CanOnlyStoreIntoArgOrLocGot0");
140                 }
141                 this.Stloc((LocalBuilder)var);
142             }
143         }
144 
145         /// <summary>
146         /// StoreArrayElement
147         /// </summary>
148         /// <param name="obj">数组对象</param>
149         /// <param name="arrayIndex">数组索引</param>
150         /// <param name="value">保存的值</param>
151                
152         public void StoreArrayElement(object obj, object arrayIndex, object value)
153         {
154             Type variableType = this.GetVariableType(obj);
155             Type objType = (variableType == typeof(Array)) ? typeof(object) : variableType.GetElementType();
156             this.Load(obj);
157             this.Load(arrayIndex);
158 
159             if (IsStruct(objType))
160             {  
161                 //Pre1:将对象引用 array 推送到堆栈上。
162                 //Pre2:将索引值 index 推送到堆栈上。
163                 //Do1:从堆栈中弹出 index 和 array;查找存储在array中的位置index 处的地址。
164                 //Do2:将地址推送到堆栈上。
165                 this.Ldelema(objType);
166             }
167 
168             this.Load(value);
169             this.ConvertValue(this.GetVariableType(value), objType);
170 
171 
172             if (IsStruct(objType))
173             {   //Pre1:   将地址推送到堆栈上。 
174                 //Pre2:   将 class 类型的值类型对象推送到堆栈上。
175                 //ToDo:   从堆栈中弹出对象和地址;将值类型对象存储在该地址。    
176                 this.Stobj(objType);
177             }
178             else
179             {
180                 //Pre1: 将对数组 array 的对象引用推送到堆栈上。
181                 //Pre2: 将array 中元素的有效索引推送到堆栈上。
182                 //Pre3:将值推送到堆栈上。
183                 //ToDo: 从堆栈中弹出值、索引和数组引用;将值放入给定索引处的数组元素中。
184                 this.Stelem(objType);
185             }
186         }
187 
188         /// <summary>
189         /// StoreMember 用新值替换在对象引用或指针的字段中存储的值
190         /// Pre:value压入栈中
191         /// </summary>
192         /// <param name="memberInfo"></param>
193         public void StoreMember(MemberInfo memberInfo)
194         {
195             Check.Require(memberInfo, "memberInfo");
196 
197             if (memberInfo.MemberType == MemberTypes.Field)
198             {
199                 FieldInfo field = (FieldInfo)memberInfo;
200                 if (field.IsStatic)
201                 {
202                     this.ilGen.Emit(OpCodes.Stsfld, field);
203                 }
204                 else
205                 {
206                     this.ilGen.Emit(OpCodes.Stfld, field);
207                 }
208             }
209             else if (memberInfo.MemberType == MemberTypes.Property)
210             {
211                 PropertyInfo info2 = memberInfo as PropertyInfo;
212                 if (info2 != null)
213                 {
214                     MethodInfo methodInfo = info2.GetSetMethod(true);
215                     if (methodInfo == null)
216                     {
217                         throw new Exception("NoSetMethodForProperty");
218                     }
219                     this.Call(methodInfo);
220                 }
221             }
222             else
223             {
224                 if (memberInfo.MemberType != MemberTypes.Method)
225                 {
226                     throw new Exception("CannotLoadMemberType");
227                 }
228                 this.Call((MethodInfo)memberInfo);
229             }
230         }
变量加载
  1   /// <summary>
  2         /// LdargAddress 加载参数地址。IL没有这个指令,它根据参数的类型分别调用不同的IL指令:
  3         /// 当参数为值类型时,通过调用Ldarga指令,加载参数地址
  4         /// 当参不为值类型时,直接调用Ldarg加载参数
  5         /// 推测:maybe, 引用类型的变量本身代表的就是其地址,而值类型变量代表的是值本身,故值类型需要取址.
  6         /// </summary>
  7         /// <param name="argBuilder"></param>
  8         public void LdargAddress(ArgBuilder argBuilder)
  9         {
 10             Check.Require(argBuilder, "argBuilder");
 11 
 12             if (argBuilder.ArgType.IsValueType)
 13             {
 14                 this.Ldarga(argBuilder);
 15             }
 16             else
 17             {
 18                 this.Ldarg(argBuilder);
 19             }
 20         }
 21 
 22 
 23         /// <summary>
 24         /// Ldelem 根据传入的数组类型,自动选择不同的指令,将位于数组指定索引处的元素加到计算堆栈 
 25         /// 这些指令包括:
 26         /// ldelem.i1       加载int8
 27         /// ldelem.u1       unsigned int8.
 28         /// ldelem.i2       int16
 29         /// ldelem.u2       unsigned int16
 30         /// ldelem.i4       int32
 31         /// ldelem.i8       int64
 32         /// ldelem.i        native int
 33         /// ldelem.r4       float32
 34         /// ldelem.r8       float64
 35         /// ldelem.ref      reference type
 36         /// </summary>
 37         /// <param name="arrayElementType"></param>
 38         public void Ldelem(Type arrayElementType)
 39         {
 40             Check.Require(arrayElementType, "arrayElementType");
 41 
 42             if (arrayElementType.IsEnum)
 43             {
 44                 this.Ldelem(Enum.GetUnderlyingType(arrayElementType));
 45             }
 46             else
 47             {
 48                 OpCode opcode = this.GetLdelemOpCode(Type.GetTypeCode(arrayElementType));
 49                 if (opcode.Equals(OpCodes.Nop))
 50                 {
 51                     throw new Exception("ArrayTypeIsNotSupported");
 52                 }
 53                 this.ilGen.Emit(opcode);
 54             }
 55         }
 56 
 57         /// <summary>
 58         /// Ldelema 将位于指定数组索引的数组元素的地址作为 & 类型(托管指针)加载到计算堆栈的顶部。
 59         /// </summary>
 60         /// <param name="arrayElementType"></param>
 61         public void Ldelema(Type arrayElementType)
 62         {
 63             Check.Require(arrayElementType, "arrayElementType");
 64 
 65             OpCode opcode = OpCodes.Ldelema;
 66             this.ilGen.Emit(opcode, arrayElementType);
 67         }
 68 
 69         /// <summary>
 70         /// Ldlen 将从零开始的、一维数组的元素的数目推送到计算堆栈上。        
 71         /// </summary>
 72         public void Ldlen()
 73         {
 74             // Pre:  将对数组的对象引用推送到堆栈上。
 75             // ToDo1:从堆栈中弹出数组引用,并计算长度。
 76             // ToDo2:将长度推送到堆栈上。
 77             this.ilGen.Emit(OpCodes.Ldlen);
 78             // Pre:  value 被推送到堆栈上。
 79             // ToDo1: 从堆栈中弹出 value,然后尝试执行转换操作。
 80             // ToDo2: 如果转换成功,则将结果值推送到堆栈上。
 81             this.ilGen.Emit(OpCodes.Conv_I4);
 82         }
 83 
 84         /// <summary>
 85         /// Ldloc 将指定索引处的局部变量加载到计算堆栈上。
 86         /// </summary>
 87         /// <param name="slot"></param>
 88         public void Ldloc(int slot)
 89         {
 90             switch (slot)
 91             {
 92                 case 0:
 93                     this.ilGen.Emit(OpCodes.Ldloc_0);
 94                     return;
 95 
 96                 case 1:
 97                     this.ilGen.Emit(OpCodes.Ldloc_1);
 98                     return;
 99 
100                 case 2:
101                     this.ilGen.Emit(OpCodes.Ldloc_2);
102                     return;
103 
104                 case 3:
105                     this.ilGen.Emit(OpCodes.Ldloc_3);
106                     return;
107             }
108             if (slot <= 0xff)
109             {
110                 this.ilGen.Emit(OpCodes.Ldloc_S, slot);
111             }
112             else
113             {
114                 this.ilGen.Emit(OpCodes.Ldloc, slot);
115             }
116         }
117 
118         /// <summary>
119         /// Ldloc 将指定索引处的局部变量加载到计算堆栈上
120         /// </summary>
121         /// <param name="localBuilder"></param>
122         public void Ldloc(LocalBuilder localBuilder)
123         {
124             this.ilGen.Emit(OpCodes.Ldloc, localBuilder);
125         }
126 
127         /// <summary>
128         /// Ldloca 将位于特定索引处的局部变量的地址加载到计算堆栈上。
129         /// 提示:ldloca.s 指令为使用局部变量 0 到 255 提供有效的编码。
130         /// </summary>
131         /// <param name="slot"></param>
132         public void Ldloca(int slot)
133         {
134             if (slot <= 0xff)
135             {
136                 this.ilGen.Emit(OpCodes.Ldloca_S, slot);
137             }
138             else
139             {
140                 this.ilGen.Emit(OpCodes.Ldloca, slot);
141             }
142         }
143 
144         /// <summary>
145         /// Ldloca
146         /// </summary>
147         /// <param name="localBuilder"></param>
148         public void Ldloca(LocalBuilder localBuilder)
149         {
150             Check.Require(localBuilder, "localBuilder");
151 
152             this.ilGen.Emit(OpCodes.Ldloca, localBuilder);
153         }
154 
155         /// <summary>
156         /// LdlocAddress 不是IL指令。
157         /// 分别调用Ldloca和Ldloc将值/引用类型变量地址加载到计算堆栈
158         /// 当是为值类型时调用 Ldloca
159         /// 否则调用 Ldloc
160         /// </summary>
161         /// <param name="localBuilder"></param>
162         public void LdlocAddress(LocalBuilder localBuilder)
163         {
164             Check.Require(localBuilder, "localBuilder");
165 
166             if (localBuilder.LocalType.IsValueType)
167             {
168                 this.Ldloca(localBuilder);
169             }
170             else
171             {
172                 this.Ldloc(localBuilder);
173             }
174         }
175 
176         /// <summary>
177         /// Ldobj 将地址指向的值类型(类型为type)对象复制到计算堆栈的顶部        
178         /// </summary>
179         /// <param name="type"></param>
180         public void Ldobj(Type type)
181         {
182             Check.Require(type, "type");
183 
184             OpCode opcode = this.GetLdindOpCode(Type.GetTypeCode(type));
185             if (!opcode.Equals(OpCodes.Nop))
186             {
187                 this.ilGen.Emit(opcode);
188             }
189             else
190             {
191                 this.ilGen.Emit(OpCodes.Ldobj, type);
192             }
193         }
194 
195         /// <summary>
196         /// Ldstr
197         /// 将一个字符串加载到 Stack
198         /// </summary>
199         /// <param name="strVar"></param>
200         public void Ldstr(string strVar)
201         {
202             this.ilGen.Emit(OpCodes.Ldstr, strVar);
203         }
204 
205         /// <summary>
206         /// Ldtoken 将元数据标记(数据类型)转换为其运行时表示形式,并将其推送到计算堆栈上。
207         /// ldtoken 指令为指定的元数据标记推送 RuntimeHandle。
208         ///   其中: RuntimeHandle 可以是 fieldref/fielddef、methodref/methoddef 或 typeref/typedef。
209         ///   说白了:就是向栈内添加 某类型的 运行时类型
210         /// </summary>
211         /// <param name="t"></param>
212         public void Ldtoken(Type t)
213         {
214             Check.Require(t, "t");
215             this.ilGen.Emit(OpCodes.Ldtoken, t);
216         }
217 
218         /// <summary>
219         /// Load
220         /// </summary>
221         /// <param name="obj"></param>
222         public void Load(object obj)
223         {
224             if (obj == null)
225             {
226                 this.ilGen.Emit(OpCodes.Ldnull); //将空对象引用推送到堆栈上
227             }
228             else if (obj is ArgBuilder)
229             {
230                 this.Ldarg((ArgBuilder)obj);
231             }
232             else if (obj is LocalBuilder)
233             {
234                 this.Ldloc((LocalBuilder)obj);
235             }
236             else
237             {
238                 this.Ldc(obj);
239             }
240         }
241 
242         /// <summary>
243         /// LoadAddress
244         /// </summary>
245         /// <param name="obj"></param>
246         public void LoadAddress(object obj)
247         {
248             if (obj is ArgBuilder)
249             {
250                 this.LdargAddress((ArgBuilder)obj);
251             }
252             else if (obj is LocalBuilder)
253             {
254                 this.LdlocAddress((LocalBuilder)obj);
255             }
256             else
257             {
258                 this.Load(obj);
259             }
260         }
261 
262         /// <summary>
263         /// LoadArrayElement
264         /// </summary>
265         /// <param name="obj"></param>
266         /// <param name="arrayIndex"></param>
267         public void LoadArrayElement(object obj, object arrayIndex)
268         {
269             Type objType = this.GetVariableType(obj).GetElementType();
270             this.Load(obj);
271             this.Load(arrayIndex);
272             if (IsStruct(objType))
273             {  //Stuct类型:先加载地址,然后寻址加载
274                 this.Ldelema(objType);
275                 this.Ldobj(objType);
276             }
277             else
278             {
279                 this.Ldelem(objType);
280             }
281         }
282 
283         /// <summary>
284         /// LoadDefaultValue
285         /// </summary>
286         /// <param name="type"></param>
287         public void LoadDefaultValue(Type type)
288         {
289             Check.Require(type, "type");
290 
291             if (!type.IsValueType)
292             {
293                 this.Load(null);
294             }
295             else
296             {
297                 switch (Type.GetTypeCode(type))
298                 {
299                     case TypeCode.Boolean:
300                         this.Ldc(false);
301                         return;
302 
303                     case TypeCode.Char:
304                     case TypeCode.SByte:
305                     case TypeCode.Byte:
306                     case TypeCode.Int16:
307                     case TypeCode.UInt16:
308                     case TypeCode.Int32:
309                     case TypeCode.UInt32:
310                         this.Ldc(0);
311                         return;
312 
313                     case TypeCode.Int64:
314                     case TypeCode.UInt64:
315                         this.Ldc((long)0);
316                         return;
317 
318                     case TypeCode.Single:
319                         this.Ldc((float)0f);
320                         return;
321 
322                     case TypeCode.Double:
323                         this.Ldc((double)0);
324                         return;
325                 }
326                 //非原始类型,一般指结构体Struct
327                 LocalBuilder builder = this.DeclareLocal(type, "zero");
328                 this.LoadAddress(builder);
329                 this.InitObj(type);
330                 this.Load(builder);
331             }
332         }
333 
334         /// <summary>
335         /// LoadMember
336         /// Return:执行后的栈顶类型
337         /// </summary>
338         /// <param name="memberInfo"></param>
339         /// <returns></returns>
340         public Type LoadMember(MemberInfo memberInfo)
341         {
342             Check.Require(memberInfo, "memberInfo");
343 
344             Type stackTopType = null;
345             if (memberInfo.MemberType == MemberTypes.Field)
346             {
347                 FieldInfo field = (FieldInfo)memberInfo;
348                 stackTopType = field.FieldType;
349                 if (field.IsStatic)
350                 {
351                     this.ilGen.Emit(OpCodes.Ldsfld, field);
352                 }
353                 else
354                 {
355                     this.ilGen.Emit(OpCodes.Ldfld, field);
356                 }
357             }
358             else if (memberInfo.MemberType == MemberTypes.Property)
359             {
360                 PropertyInfo info2 = memberInfo as PropertyInfo;
361                 stackTopType = info2.PropertyType;
362                 if (info2 != null)
363                 {
364                     MethodInfo methodInfo = info2.GetGetMethod(true);
365                     if (methodInfo == null)
366                     {
367                         throw new Exception("NoGetMethodForProperty");
368                     }
369                     this.Call(methodInfo);
370                 }
371             }
372             else
373             {
374                 if (memberInfo.MemberType != MemberTypes.Method)
375                 {
376                     throw new Exception("CannotLoadMemberType");
377                 }
378                 MethodInfo info4 = (MethodInfo)memberInfo;
379                 stackTopType = info4.ReturnType;
380                 this.Call(info4);
381             }
382             return stackTopType;
383         }
384 
385         /// <summary>
386         /// LoadParam:加载一个参数:加载对象,并转换为方法中参数的类型
387         /// </summary>
388         /// <param name="arg"></param>
389         /// <param name="oneBasedArgIndex"></param>
390         /// <param name="methodInfo"></param>
391         private void LoadParam(object arg, int oneBasedArgIndex, MethodBase methodInfo)
392         {
393             this.Load(arg);
394             if (arg != null)
395             {
396                 this.ConvertValue(this.GetVariableType(arg), methodInfo.GetParameters()[oneBasedArgIndex - 1].ParameterType);
397             }
398         }
399 
400         /// <summary>
401         /// LoadThis:加载对象,并转换为
402         /// </summary>
403         /// <param name="thisObj"></param>
404         /// <param name="methodInfo"></param>
405         private void LoadThis(object thisObj, MethodInfo methodInfo)
406         {
407             if ((thisObj != null) && !methodInfo.IsStatic)
408             {
409                 this.LoadAddress(thisObj);
410                 this.ConvertAddress(this.GetVariableType(thisObj), methodInfo.DeclaringType);
411             }
412         }
加载 [参数||参数地址]
 1   /// <summary>
 2         /// Ldarg 加载第solt参数到堆栈
 3         /// 注意:实例方法都有一个隐含参数,也就是第0个参数是表示当前对象引用 也就是 this指针
 4         /// </summary>
 5         /// <param name="slot">The slot.</param>
 6         public void Ldarg(int slot)
 7         {
 8             switch (slot)
 9             {
10                 case 0:
11                     this.ilGen.Emit(OpCodes.Ldarg_0);
12                     return;
13 
14                 case 1:
15                     this.ilGen.Emit(OpCodes.Ldarg_1);
16                     return;
17 
18                 case 2:
19                     this.ilGen.Emit(OpCodes.Ldarg_2);
20                     return;
21 
22                 case 3:
23                     this.ilGen.Emit(OpCodes.Ldarg_3);
24                     return;
25             }
26             if (slot <= 0xff)
27             {
28                 //将参数(由指定的短格式索引引用)加载到计算堆栈上。
29                 this.ilGen.Emit(OpCodes.Ldarg_S, slot);
30             }
31             else
32             {
33                 this.ilGen.Emit(OpCodes.Ldarg, slot);
34             }
35         }
36 
37         /// <summary>
38         /// Ldarg 调用Ldarg(int)的重载方式
39         /// </summary>
40         /// <param name="arg"></param>
41         public void Ldarg(ArgBuilder arg)
42         {
43             Check.Require(arg, "arg");
44 
45             this.Ldarg(arg.Index);
46         }
47 
48         /// <summary>
49         /// Ldarga 将参数的地址加载到计算堆栈=>注意是加载地址
50         /// 自动判断是使用Ldarga_S,还是Ldarga
51         /// Ldarga_S 指令是用于slot值在 0 到 255的参数编号,效率更高的编码
52         /// </summary>
53         /// <param name="slot"></param>
54         public void Ldarga(int slot)
55         {
56             if (slot <= 0xff)
57             {
58                 this.ilGen.Emit(OpCodes.Ldarga_S, slot);
59             }
60             else
61             {
62                 this.ilGen.Emit(OpCodes.Ldarga, slot);
63             }
64         }
65 
66         /// <summary>
67         /// Ldarga 调用 Ldarga(int) 重载
68         /// </summary>
69         /// <param name="argBuilder"></param>
70         public void Ldarga(ArgBuilder argBuilder)
71         {
72             Check.Require(argBuilder, "argBuilder");
73 
74             this.Ldarga(argBuilder.Index);
75         }

类型方面:

创建构建
 1   /// <summary>
 2         /// InitObj:初始化值类型
 3         ///    Pre1: 将要初始化的值类型的地址推送到堆栈上。
 4         ///    TODO: 从堆栈中弹出地址;将位于指定地址的值类型初始化为 typeTok 类型。
 5         ///    提示: 与 Newobj 不同,initobj 不会调用构造函数方法。 Initobj 用于初始化值类型,而 newobj 用于分配和初始化对象。
 6         /// </summary>
 7         /// <param name="valueType"></param>
 8         public void InitObj(Type valueType)
 9         {
10             Check.Require(valueType, "valueType");
11 
12             this.ilGen.Emit(OpCodes.Initobj, valueType);
13         }
14       
15 
16         /// <summary>
17         /// New:初始化引用类型
18         /// </summary>
19         /// <param name="constructorInfo"></param>
20         public void New(ConstructorInfo constructorInfo)
21         {
22             Check.Require(constructorInfo, "constructorInfo");
23              //Pre1:将从 arg1 到 argn 的参数按顺序推送到堆栈上。
24              //Do1:从堆栈中弹出从 argn 到 arg1 的参数并将它们传递到 ctor 以用于对象创建。
25              //Do2:将对新对象的引用推送到堆栈上。
26             this.ilGen.Emit(OpCodes.Newobj, constructorInfo);
27         }
28 
29         /// <summary>
30         /// New:带一个参数的构建方法
31         /// </summary>
32         /// <param name="constructorInfo"></param>
33         /// <param name="param1"></param>
34         public void New(ConstructorInfo constructorInfo, object param1)
35         {
36             Check.Require(constructorInfo, "constructorInfo");
37 
38             this.LoadParam(param1, 1, constructorInfo);
39             this.New(constructorInfo);
40         }
41 
42         /// <summary>
43         /// NewArray:构造数组
44         /// </summary>
45         /// <param name="elementType"></param>
46         /// <param name="len"></param>
47         public void NewArray(Type elementType, object len)
48         {
49             Check.Require(elementType, "elementType");
50 
51             this.Load(len);
52             this.ilGen.Emit(OpCodes.Newarr, elementType);
53         }
类型转换
  1      /// <summary>
  2         /// InternalConvert:
  3         /// </summary>
  4         /// <param name="source"></param>
  5         /// <param name="target"></param>
  6         /// <param name="isAddress"></param>
  7         private void InternalConvert(Type source, Type target, bool isAddress)
  8         {
  9             if (target != source)
 10             {
 11                 if (target.IsValueType)
 12                 {    //都为值类型
 13                     if (source.IsValueType)
 14                     {
 15                         OpCode opcode = this.GetConvOpCode(Type.GetTypeCode(target));
 16                         if (opcode.Equals(OpCodes.Nop))
 17                         {
 18                             throw new Exception("NoConversionPossible");
 19                         }
 20                         this.ilGen.Emit(opcode);
 21                     }
 22                     else
 23                     {
 24                         if (!source.IsAssignableFrom(target))
 25                         {
 26                             throw new Exception("IsNotAssignableFrom");
 27                         }
 28                         //source引用类型 变为target值类型
 29                         this.Unbox(target);
 30                         if (!isAddress)
 31                         {
 32                             this.Ldobj(target);
 33                         }
 34                     }
 35                 }                   
 36                 //target=source; source继承于target==>target,source都是引用类型
 37                 else if (target.IsAssignableFrom(source))
 38                 {
 39                     if (source.IsValueType)
 40                     {   //栈顶是source对象的地址
 41                         if (isAddress)
 42                         {
 43                             this.Ldobj(source);
 44                         }
 45                         this.Box(source);
 46                     }
 47                 }
 48                     //source=target;target继承于source 
 49                 else if (source.IsAssignableFrom(target))
 50                 {
 51                     this.Castclass(target);
 52                 }
 53                 else 
 54                 {
 55                     if (!target.IsInterface && !source.IsInterface)
 56                     {
 57                         throw new Exception("IsNotAssignableFrom");
 58                     }
 59                     this.Castclass(target);
 60                 }
 61             }
 62         }
 63 
 64         /// <summary>
 65         /// ConvertAddress
 66         /// </summary>
 67         /// <param name="source"></param>
 68         /// <param name="target"></param>
 69         public void ConvertAddress(Type source, Type target)
 70         {
 71             Check.Require(source, "source");
 72             Check.Require(target, "target");
 73 
 74             this.InternalConvert(source, target, true);
 75         }
 76 
 77         /// <summary>
 78         /// ConvertValue
 79         /// </summary>
 80         /// <param name="source"></param>
 81         /// <param name="target"></param>
 82         public void ConvertValue(Type source, Type target)
 83         {
 84             Check.Require(source, "source");
 85             Check.Require(target, "target");
 86 
 87             this.InternalConvert(source, target, false);
 88         }
 89 
 90 
 91         /// <summary>
 92         /// Castclass
 93         /// </summary>
 94         /// <param name="target"></param>
 95         public void Castclass(Type target)
 96         {
 97             Check.Require(target, "target");
 98 
 99             this.ilGen.Emit(OpCodes.Castclass, target);
100         }
101 
102         /// <summary>
103         /// Box
104         /// </summary>
105         /// <param name="type"></param>
106         public void Box(Type type)
107         {
108             Check.Require(type, "type");
109             Check.Require(type.IsValueType, "type MUST be ValueType");
110 
111             this.ilGen.Emit(OpCodes.Box, type);
112         }
113 
114         /// <summary>
115         /// Unbox
116         /// </summary>
117         /// <param name="type"></param>
118         public void Unbox(Type type)
119         {
120             Check.Require(type, "type");
121             Check.Require(type.IsValueType, "type MUST be ValueType");
122             //pre:  将对象引用推送到堆栈上
123             //Do1:  从堆栈中弹出对象引用并取消装箱为值类型指针
124             //Do2:  将值类型指针推送到堆栈上
125             //Result:栈顶保存值类型的指针
126             this.ilGen.Emit(OpCodes.Unbox, type);
127             //如果需将值加载到堆栈上=>ldobj
128             //Pre:将值类型对象的地址推送到地址上。
129             //Do1:从堆栈中弹出该地址并查找位于该特定地址处的实例。
130             //Do2:将存储在该地址处的对象的值推送到堆栈上。
131         }
132 
133         /// <summary>
134         /// UnboxAny
135         /// 当应用于值类型的已装箱形式时,unbox.any 指令提取 obj(类型为 O)中包含的值,因此等效于 unbox 后跟 ldobj。
136         /// 当应用于引用类型时,unbox.any 指令与 castclass 效果相同。 
137         /// </summary>
138         /// <param name="type"></param>
139         public void UnboxAny(Type type)
140         {
141             Check.Require(type, "type");
142             Check.Require(type.IsValueType, "type MUST be ValueType");
143             //Pre: 将对象引用 obj 推送到堆栈上
144             //Do1: 从堆栈中弹出对象引用,取消装箱到指令中指定的类型
145             //Do2: 将结果对象引用或值类型推送到堆栈上
146             //Result:栈顶保存值类型的值
147             this.ilGen.Emit(OpCodes.Unbox_Any, type);
148 
149             //castclass 指令
150             //  将对象引用推送到堆栈上
151             //  从堆栈中弹出对象引用;引用的对象被转换为指定的 class
152             //  如果成功,则新对象引用被推送到堆栈上
153         }

运算符:

算式运算符
 1   /// <summary>
 2         /// Add
 3         /// </summary>
 4         public void Add()
 5         {
 6             this.ilGen.Emit(OpCodes.Add);
 7         }
 8         /// <summary>
 9         /// Inc
10         /// </summary>
11         /// <param name="var"></param>
12         public void Inc(object var)
13         {
14             this.Load(var);
15             this.Load(1);
16             this.Add();
17             this.Store(var);
18         }
19         /// <summary>
20         /// Dec
21         /// </summary>
22         /// <param name="var"></param>
23         public void Dec(object var)
24         {
25             this.Load(var);
26             this.Load(1);
27             this.Subtract();
28             this.Store(var);
29         }
30         /// <summary>
31         /// Subtract
32         /// </summary>
33         public void Subtract()
34         {
35             this.ilGen.Emit(OpCodes.Sub);
36         }
位运算符
 1    /// <summary>
 2         /// And
 3         /// </summary>
 4         public void And()
 5         {
 6             this.ilGen.Emit(OpCodes.And);
 7         }
 8         /// <summary>
 9         /// Not
10         /// </summary>
11         public void Not()
12         {
13             this.ilGen.Emit(OpCodes.Not);
14         }
15 
16         /// <summary>
17         /// Or
18         /// </summary>
19         public void Or()
20         {
21             this.ilGen.Emit(OpCodes.Or);
22         }
关系运算符
1    /// <summary>
2         /// Ceq
3         /// </summary>
4         public void Ceq()
5         {
6             this.ilGen.Emit(OpCodes.Ceq);
7         }

公共操作:

指令获取
  1    private OpCode GetBranchCode(Cmp cmp)
  2         {
  3             switch (cmp)
  4             {
  5                 case Cmp.LessThan:
  6                     return OpCodes.Bge;
  7 
  8                 case Cmp.EqualTo:
  9                     return OpCodes.Bne_Un;
 10 
 11                 case Cmp.LessThanOrEqualTo:
 12                     return OpCodes.Bgt;
 13 
 14                 case Cmp.GreaterThan:
 15                     return OpCodes.Ble;
 16 
 17                 case Cmp.NotEqualTo:
 18                     return OpCodes.Beq;
 19             }
 20             return OpCodes.Blt;
 21         }
 22 
 23         //相反的比较关系
 24         private Cmp GetCmpInverse(Cmp cmp)
 25         {
 26             switch (cmp)
 27             {
 28                 case Cmp.LessThan:
 29                     return Cmp.GreaterThanOrEqualTo;
 30 
 31                 case Cmp.EqualTo:
 32                     return Cmp.NotEqualTo;
 33 
 34                 case Cmp.LessThanOrEqualTo:
 35                     return Cmp.GreaterThan;
 36 
 37                 case Cmp.GreaterThan:
 38                     return Cmp.LessThanOrEqualTo;
 39 
 40                 case Cmp.NotEqualTo:
 41                     return Cmp.EqualTo;
 42             }
 43             return Cmp.LessThan;
 44         }
 45 
 46         private OpCode GetConvOpCode(TypeCode typeCode)
 47         {
 48             switch (typeCode)
 49             {
 50                 case TypeCode.Boolean:
 51                     //Pre:value 被推送到堆栈上。
 52                     //Do1:从堆栈中弹出 value,然后尝试执行转换操作。
 53                     //Do2:如果转换成功,则将结果值推送到堆栈上。
 54                     return OpCodes.Conv_I1;
 55 
 56                 case TypeCode.Char:
 57                     return OpCodes.Conv_I2;
 58 
 59                 case TypeCode.SByte:
 60                     return OpCodes.Conv_I1;
 61 
 62                 case TypeCode.Byte:
 63                     return OpCodes.Conv_U1;
 64 
 65                 case TypeCode.Int16:
 66                     return OpCodes.Conv_I2;
 67 
 68                 case TypeCode.UInt16:
 69                     return OpCodes.Conv_U2;
 70 
 71                 case TypeCode.Int32:
 72                     return OpCodes.Conv_I4;
 73 
 74                 case TypeCode.UInt32:
 75                     return OpCodes.Conv_U4;
 76 
 77                 case TypeCode.Int64:
 78                     return OpCodes.Conv_I8;
 79 
 80                 case TypeCode.UInt64:
 81                     return OpCodes.Conv_I8;
 82 
 83                 case TypeCode.Single:
 84                     return OpCodes.Conv_R4;
 85 
 86                 case TypeCode.Double:
 87                     return OpCodes.Conv_R8;
 88             }
 89             return OpCodes.Nop;
 90         }
 91 
 92         private OpCode GetLdelemOpCode(TypeCode typeCode)
 93         {
 94             switch (typeCode)
 95             {
 96                 case TypeCode.Object:
 97                 case TypeCode.DBNull:
 98                     return OpCodes.Ldelem_Ref;
 99 
100                 case TypeCode.Boolean:
101                     return OpCodes.Ldelem_I1;
102 
103                 case TypeCode.Char:
104                     return OpCodes.Ldelem_I2;
105 
106                 case TypeCode.SByte:
107                     return OpCodes.Ldelem_I1;
108 
109                 case TypeCode.Byte:
110                     return OpCodes.Ldelem_U1;
111 
112                 case TypeCode.Int16:
113                     //Pre1:将对象引用 array 推送到堆栈上。
114                     //Pre2:将索引值 index 推送到堆栈上。
115                     //Do1:从堆栈中弹出 index 和 array;查找存储在 array 中的位置 index 处的值。
116                     //Do2:将值推送到堆栈上。
117                     return OpCodes.Ldelem_I2;
118 
119                 case TypeCode.UInt16:
120                     return OpCodes.Ldelem_U2;
121 
122                 case TypeCode.Int32:
123                     return OpCodes.Ldelem_I4;
124 
125                 case TypeCode.UInt32:
126                     return OpCodes.Ldelem_U4;
127 
128                 case TypeCode.Int64:
129                     return OpCodes.Ldelem_I8;
130 
131                 case TypeCode.UInt64:
132                     return OpCodes.Ldelem_I8;
133 
134                 case TypeCode.Single:
135                     return OpCodes.Ldelem_R4;
136 
137                 case TypeCode.Double:
138                     return OpCodes.Ldelem_R8;
139 
140                 case TypeCode.String:
141                     return OpCodes.Ldelem_Ref;
142             }
143             return OpCodes.Nop;
144         }
145 
146         /// <summary>
147         /// 根据值类型,返回使用哪个指令将值类型复制到计算堆栈上(ldobj指令的功能)
148         /// 间址寻址 取数
149         /// 所有 ldind 指令都是指定相应内置值类的 Ldobj 指令的快捷方式 
150         /// </summary>
151         /// <param name="typeCode">The type code.</param>
152         /// <returns></returns>
153         private OpCode GetLdindOpCode(TypeCode typeCode)
154         {
155             switch (typeCode)
156             {
157                 case TypeCode.Boolean:
158                     //将 int8 类型的值作为 int32 间接加载到计算堆栈上。
159                     //也就是:将位于栈顶的地址,所对应的int8,作为int32加载到堆栈上。
160 
161                     return OpCodes.Ldind_I1;
162 
163                 case TypeCode.Char:
164                     return OpCodes.Ldind_I2;
165 
166                 case TypeCode.SByte:
167                     return OpCodes.Ldind_I1;
168 
169                 case TypeCode.Byte:
170                     return OpCodes.Ldind_U1;
171 
172                 case TypeCode.Int16:
173                     return OpCodes.Ldind_I2;
174 
175                 case TypeCode.UInt16:
176                     return OpCodes.Ldind_U2;
177 
178                 case TypeCode.Int32:
179                     return OpCodes.Ldind_I4;
180 
181                 case TypeCode.UInt32:
182                     return OpCodes.Ldind_U4;
183                 //请注意,小于 4 个字节的整数值在加载到计算堆栈上时会被扩展为 int32
184                 //
185                 case TypeCode.Int64:
186                     return OpCodes.Ldind_I8;
187 
188                 case TypeCode.UInt64:
189                     return OpCodes.Ldind_I8;
190 
191                 case TypeCode.Single:
192                     return OpCodes.Ldind_R4;
193 
194                 case TypeCode.Double:
195                     return OpCodes.Ldind_R8;
196 
197                 case TypeCode.String:
198                     //将地址 addr 处的对象引用作为 O 类型加载到堆栈上                    
199                     return OpCodes.Ldind_Ref;
200             }
201             return OpCodes.Nop;
202         }
203 
204         private OpCode GetStelemOpCode(TypeCode typeCode)
205         {
206             switch (typeCode)
207             {
208                 case TypeCode.Object:
209                 case TypeCode.DBNull:
210                     //用计算堆栈上的对象 ref 值(O 类型)替换给定索引处的数组元素。
211                     return OpCodes.Stelem_Ref;
212 
213                 case TypeCode.Boolean:
214                     return OpCodes.Stelem_I1;
215 
216                 case TypeCode.Char:
217                     return OpCodes.Stelem_I2;
218 
219                 case TypeCode.SByte:
220                     return OpCodes.Stelem_I1;
221 
222                 case TypeCode.Byte:
223                     return OpCodes.Stelem_I1;
224 
225                 case TypeCode.Int16:
226                     return OpCodes.Stelem_I2;
227 
228                 case TypeCode.UInt16:
229                     //How:用计算堆栈上的 int16 值替换给定索引处的数组元素。
230                     //Pre1: 将对数组 array 的对象引用推送到堆栈上。
231                     //Pre2: 将array 中元素的有效索引推送到堆栈上。
232                     //Pre3:将值推送到堆栈上。
233                     //ToDo: 从堆栈中弹出值、索引和数组引用;将值放入给定索引处的数组元素中。
234                     return OpCodes.Stelem_I2;
235 
236                 case TypeCode.Int32:
237                     return OpCodes.Stelem_I4;
238 
239                 case TypeCode.UInt32:
240                     return OpCodes.Stelem_I4;
241 
242                 case TypeCode.Int64:
243                     return OpCodes.Stelem_I8;
244 
245                 case TypeCode.UInt64:
246                     return OpCodes.Stelem_I8;
247 
248                 case TypeCode.Single:
249                     return OpCodes.Stelem_R4;
250 
251                 case TypeCode.Double:
252                     return OpCodes.Stelem_R8;
253 
254                 case TypeCode.String:
255                     return OpCodes.Stelem_Ref;
256             }
257             return OpCodes.Nop;
258         }
常用方法
 1   /// <summary>
 2         /// DefineLabel
 3         /// </summary>
 4         /// <returns></returns>
 5         public Label DefineLabel()
 6         {
 7             return this.ilGen.DefineLabel();
 8         }
 9 
10         /// <summary>
11         /// MarkLabel
12         /// </summary>
13         /// <param name="label"></param>
14         public void MarkLabel(Label label)
15         {   
16             //不能多次定义一个标签
17             this.ilGen.MarkLabel(label);
18         }
19 
20         /// <summary>
21         /// Dup:对堆栈顶部的数据 进行拷贝
22         /// </summary>
23         public void Dup()
24         {
25             this.ilGen.Emit(OpCodes.Dup);
26         }
27 
28          
29         /// <summary>
30         /// GetArg
31         /// </summary>
32         /// <param name="index"></param>
33         /// <returns></returns>
34         public ArgBuilder GetArg(int index)
35         {
36             return (ArgBuilder)this.argList[index];
37         }
38          
39         /// <summary>
40         /// GetVariableType
41         /// </summary>
42         /// <param name="var"></param>
43         /// <returns></returns>
44         public Type GetVariableType(object var)
45         {
46             if (var is ArgBuilder)
47             {
48                 return ((ArgBuilder)var).ArgType;
49             }
50             if (var is LocalBuilder)
51             {
52                 return ((LocalBuilder)var).LocalType;
53             }
54             return var.GetType();
55         } 
56 
57         private static bool IsStruct(Type objType)
58         {
59             if (objType.IsValueType)
60             {
61                 return !objType.IsPrimitive; //非原始的数值类型:也就是非int,long,bool等类型
62             }
63             return false;
64         }
65 
66 
67         /// <summary>
68         /// Pop:两个指令集有何区别
69         /// a=GetAge();
70         /// GetAge();
71         /// 前者需要将栈顶的值弹入a中,后者从栈顶弹出不保存
72         /// 前者是一个保存操作,后者即是Pop操作
73         /// </summary>
74         public void Pop()
75         {
76             this.ilGen.Emit(OpCodes.Pop);
77         }
78 
79         /// <summary>
80         /// Throw
81         /// </summary>
82         public void Throw()
83         {
84             this.ilGen.Emit(OpCodes.Throw);
85         }
86 
87         private void ThrowMismatchException(object expected)
88         {
89             throw new Exception("ExpectingEnd");
90         }

结构语句:

条件跳转
 1  /// <summary>
 2         /// Bgt
 3         /// </summary>
 4         /// <param name="label"></param>
 5         public void Bgt(Label label)
 6         {
 7             this.ilGen.Emit(OpCodes.Bgt, label);
 8         }
 9 
10         /// <summary>
11         /// Ble
12         /// </summary>
13         /// <param name="label"></param>
14         public void Ble(Label label)
15         {
16             this.ilGen.Emit(OpCodes.Ble, label);
17         }
18 
19         /// <summary>
20         /// Blt
21         /// </summary>
22         /// <param name="label"></param>
23         public void Blt(Label label)
24         {
25             this.ilGen.Emit(OpCodes.Blt, label);
26         }
27 
28         /// <summary>
29         /// Br 无条件地将控制转移到目标指令
30         /// </summary>
31         /// <param name="label"></param>
32         public void Br(Label label)
33         {
34             this.ilGen.Emit(OpCodes.Br, label);
35         }
36 
37         /// <summary>
38         /// Brfalse
39         /// </summary>
40         /// <param name="label"></param>
41         public void Brfalse(Label label)
42         {
43             this.ilGen.Emit(OpCodes.Brfalse, label);
44         }
45 
46         /// <summary>
47         /// Brtrue
48         /// </summary>
49         /// <param name="label"></param>
50         public void Brtrue(Label label)
51         {
52             this.ilGen.Emit(OpCodes.Brtrue, label);
53         }

If语句
  1         /// <summary>
  2         /// If
  3         /// </summary>
  4         /// <param name="value1"></param>
  5         /// <param name="cmpOp"></param>
  6         /// <param name="value2"></param>
  7         public void If(object value1, Cmp cmpOp, object value2)
  8         {
  9             this.Load(value1);
 10             this.Load(value2);
 11             this.If(cmpOp);
 12         }
 13 
 14         /// <summary>
 15         /// If
 16         /// </summary>
 17         /// <param name="cmpOp"></param>
 18         public void If(Cmp cmpOp)
 19         {
 20             //if(a==b){  }          
 21             IfState state = new IfState();
 22             state.EndIf = this.DefineLabel();
 23             state.ElseBegin = this.DefineLabel();
 24             this.ilGen.Emit(this.GetBranchCode(cmpOp), state.ElseBegin);
 25             this.blockStack.Push(state);
 26         }
 27   /// <summary>
 28         /// ElseIf
 29         /// </summary>
 30         /// <param name="value1"></param>
 31         /// <param name="cmpOp"></param>
 32         /// <param name="value2"></param>
 33         public void ElseIf(object value1, Cmp cmpOp, object value2)
 34         {
 35             IfState state = (IfState)this.blockStack.Pop();
 36             this.Br(state.EndIf);
 37             this.MarkLabel(state.ElseBegin);
 38             this.Load(value1);
 39             this.Load(value2);
 40             state.ElseBegin = this.DefineLabel();
 41             this.ilGen.Emit(this.GetBranchCode(cmpOp), state.ElseBegin);
 42             this.blockStack.Push(state);
 43         }
 44 
 45 
 46         /// <summary>
 47         /// Else
 48         /// </summary>
 49         public void Else()
 50         {
 51             IfState state = this.PopIfState();
 52             this.Br(state.EndIf);
 53             this.MarkLabel(state.ElseBegin);
 54             state.ElseBegin = state.EndIf;
 55             this.blockStack.Push(state);
 56         }
 57              
 58 
 59         /// <summary>
 60         /// EndIf
 61         /// </summary>
 62         public void EndIf()
 63         {
 64             IfState state = this.PopIfState();
 65             if (!state.ElseBegin.Equals(state.EndIf))
 66             {
 67                 this.MarkLabel(state.ElseBegin);
 68             }
 69             this.MarkLabel(state.EndIf);
 70         }
 71 
 72 
 73 
 74     
 75 
 76         /// <summary>
 77         /// If
 78         /// </summary>
 79         public void If()
 80         {
 81             this.InternalIf(false);
 82         }
 83         /// <summary>
 84         /// IfNot
 85         /// </summary>
 86         public void IfNot()
 87         {
 88             this.InternalIf(true);
 89         }
 90         private void InternalIf(bool negate)
 91         {
 92             IfState state = new IfState();
 93             state.EndIf = this.DefineLabel();
 94             state.ElseBegin = this.DefineLabel();
 95             if (negate)
 96             {
 97                 this.Brtrue(state.ElseBegin);
 98             }
 99             else
100             {
101                 this.Brfalse(state.ElseBegin);
102             }
103             this.blockStack.Push(state);
104         }
105 
106 
107     
108         /// <summary>
109         /// IfNotDefaultValue
110         /// </summary>
111         /// <param name="value"></param>
112         public void IfNotDefaultValue(object value)
113         {
114             Type variableType = this.GetVariableType(value);
115             TypeCode typeCode = Type.GetTypeCode(variableType);
116             if (((typeCode == TypeCode.Object) && variableType.IsValueType) || ((typeCode == TypeCode.DateTime) || (typeCode == TypeCode.Decimal)))
117             {
118                 this.LoadDefaultValue(variableType);
119                 this.ConvertValue(variableType, typeof(object));
120                 this.Load(value);
121                 this.ConvertValue(variableType, typeof(object));
122                 this.Call(ObjectEquals);
123                 this.IfNot();
124             }
125             else
126             {
127                 this.LoadDefaultValue(variableType);
128                 this.Load(value);
129                 this.If(Cmp.NotEqualTo);
130             }
131         }    
132 
133         private IfState PopIfState()
134         {
135             object expected = this.blockStack.Pop();
136             IfState state = expected as IfState;
137             if (state == null)
138             {
139                 this.ThrowMismatchException(expected);
140             }
141             return state;
142         }
If语句示意[有Else]
 1  //  if(...) Goto  BeginIf
 2       
 3            ////{IfCode}
 4 
 5         //        Goto  EndIf 
 6         //:BeginIf
 7         //  if(...) Goto ElseIf1        
 8 
 9           ////{Else-IfCode}
10          
11         //    Goto Endif
12         //:ElseIf1
13         //   if(...) Goto ElseIf2
14 
15             ////{ElseCode} 
16 
17          ////注:(ElseIf2==EndIf),差异是无ElseIf2
18         //:EndIf
If语句示意[无Else]
 1    //  if(...) Goto  BeginIf
 2 
 3              //{If-Code}
 4 
 5         //        Goto  EndIf 
 6         //:BeginIf
 7         //  if(...) Goto ElseIf1        
 8 
 9             //{Else-IfCode}
10 
11         //    Goto Endif
12         //:ElseIf1
13         //   if(...) Goto ElseIf2
14 
15             //{Else-IfCode}
16 
17         //:ElseIf2
18         //:EndIf
Switch语句
 1 /// <summary>
 2         /// Switch
 3         /// </summary>
 4         /// <param name="labelCount"></param>
 5         /// <returns></returns>
 6         public Label[] Switch(int labelCount)
 7         {
 8             SwitchState state = new SwitchState(this.DefineLabel(), this.DefineLabel());
 9             Label[] labels = new Label[labelCount];
10             for (int i = 0; i < labels.Length; i++)
11             {
12                 labels[i] = this.DefineLabel();
13             }
14             this.ilGen.Emit(OpCodes.Switch, labels);
15             this.Br(state.DefaultLabel);
16             this.blockStack.Push(state);
17             return labels;
18         }
19 
20 
21         /// <summary>
22         /// Case
23         /// </summary>
24         /// <param name="caseLabel1"></param>
25         /// <param name="caseLabelName"></param>
26         public void Case(Label caseLabel1, string caseLabelName)
27         {
28             this.MarkLabel(caseLabel1);
29         }
30         /// <summary>
31         /// DefaultCase:开始default代码块
32         /// </summary>
33         public void DefaultCase()
34         {
35             object expected = this.blockStack.Peek();
36             SwitchState state = expected as SwitchState;
37             if (state == null)
38             {
39                 this.ThrowMismatchException(expected);
40             }
41             this.MarkLabel(state.DefaultLabel);
42             state.DefaultDefined = true;
43         }
44      
45 
46         /// <summary>
47         /// EndCase:相当于Switch中的break
48         /// </summary>
49         public void EndCase()
50         {
51             object expected = this.blockStack.Peek();
52             SwitchState state = expected as SwitchState;
53             if (state == null)
54             {
55                 this.ThrowMismatchException(expected);
56             }
57             this.Br(state.EndOfSwitchLabel);
58         }
59         /// <summary>
60         /// EndSwitch
61         /// </summary>
62         public void EndSwitch()
63         {
64             object expected = this.blockStack.Pop();
65             SwitchState state = expected as SwitchState;
66             if (state == null)
67             {
68                 this.ThrowMismatchException(expected);
69             }
70             if (!state.DefaultDefined)
71             {
72                 this.MarkLabel(state.DefaultLabel);
73             }
74             this.MarkLabel(state.EndOfSwitchLabel);
75         } 
For||Foreach
  1  /// <summary>
  2         /// For
  3         /// </summary>
  4         /// <param name="local"></param>
  5         /// <param name="start"></param>
  6         /// <param name="end"></param>
  7         /// <returns></returns>
  8         public object For(LocalBuilder local, object start, object end)
  9         {
 10             Check.Require(local, "local");
 11 
 12             ForState state = new ForState(local, this.DefineLabel(), this.DefineLabel(), end);
 13             if (state.Index != null)
 14             {
 15                 this.Load(start);
 16                 this.Stloc(state.Index);
 17                 this.Br(state.TestLabel);
 18             }
 19             this.MarkLabel(state.BeginLabel);
 20             this.blockStack.Push(state);
 21             return state;
 22         }
 23         //    Index=start;     
 24         // Begin:
 25         //  
 26         //    Index++;
 27         // Test:
 28         //   if(Index<N) goto :Begin
 29         //
 30         // End:
 31         /// <summary>
 32         /// EndFor
 33         /// </summary>
 34         public void EndFor()
 35         {
 36             object expected = this.blockStack.Pop();
 37             ForState state = expected as ForState;
 38             if (state == null)
 39             {
 40                 this.ThrowMismatchException(expected);
 41             }
 42             if (state.Index != null)
 43             {  
 44                 //Inc: Index++
 45                 this.Ldloc(state.Index);
 46                 this.Ldc(1);
 47                 this.Add();
 48                 this.Stloc(state.Index);
 49 
 50                 this.MarkLabel(state.TestLabel);
 51 
 52                 //if(i<n) goto begin
 53                 this.Ldloc(state.Index);//加载:局部变量 与 常量的区别
 54                 //加载Length或循环n
 55                 this.Load(state.End);
 56                 if (this.GetVariableType(state.End).IsArray)
 57                 {
 58                     this.Ldlen();
 59                 }
 60                 this.Blt(state.BeginLabel);
 61             }
 62             else
 63             {   //while(true)
 64                 this.Br(state.BeginLabel);
 65             }
 66              //如果需要,则添加End标签
 67             if (state.RequiresEndLabel)
 68             {  
 69                 this.MarkLabel(state.EndLabel);
 70             }
 71         }
 72            
 73         
 74         /// <summary>
 75         /// ForEach
 76         /// </summary>
 77         /// <param name="local">当前元素接受变量</param>
 78         /// <param name="elementType">元素类型</param>
 79         /// <param name="enumeratorType">enumerator类型</param>
 80         /// <param name="enumerator">enumerator实例</param>
 81         /// <param name="getCurrentMethod">enumerator类型Getcurrent方法</param>
 82         public void ForEach(LocalBuilder local, Type elementType, Type enumeratorType, LocalBuilder enumerator, MethodInfo getCurrentMethod)
 83         {
 84             Check.Require(local, "local");
 85             Check.Require(elementType, "elementType");
 86             Check.Require(enumeratorType, "enumeratorType");
 87             Check.Require(enumerator, "enumerator");
 88             Check.Require(getCurrentMethod, "getCurrentMethod");
 89 
 90             ForState state = new ForState(local, this.DefineLabel(), this.DefineLabel(), enumerator);
 91             this.Br(state.TestLabel);
 92             this.MarkLabel(state.BeginLabel);
 93             if (enumeratorType == getCurrentMethod.DeclaringType)
 94             {
 95                 this.LoadThis(enumerator, getCurrentMethod);
 96                 this.ilGen.Emit(OpCodes.Call, getCurrentMethod);
 97             }
 98             else
 99             {
100                 this.Call(enumerator, getCurrentMethod);
101             }
102             this.ConvertValue(elementType, this.GetVariableType(local));
103             this.Stloc(local);
104             this.blockStack.Push(state);
105         }
106 
107         //  Goto Test
108         //Begin:
109         //  local=(elementType)GetCurrent()
110         ///// [ForCode]
111         //:Test
112         //   if(MoveNext()==true) Goto Begin
113         //:End
114 
115         /// <summary>
116         /// EndForEach
117         /// </summary>
118         /// <param name="moveNextMethod"></param>
119         public void EndForEach(MethodInfo moveNextMethod)
120         {
121             Check.Require(moveNextMethod, "moveNextMethod");
122 
123             object expected = this.blockStack.Pop();
124             ForState state = expected as ForState;
125             if (state == null)
126             {
127                 this.ThrowMismatchException(expected);
128             }
129             this.MarkLabel(state.TestLabel);
130             object var = state.End;
131             if (this.GetVariableType(var) == moveNextMethod.DeclaringType)
132             {
133                 this.LoadThis(var, moveNextMethod);
134                 this.ilGen.Emit(OpCodes.Call, moveNextMethod);
135             }
136             else
137             {
138                 this.Call(var, moveNextMethod);
139             }
140             this.Brtrue(state.BeginLabel);
141             if (state.RequiresEndLabel)
142             {
143                 this.MarkLabel(state.EndLabel);
144             }
145         }
146 
147      
148         /// <summary>
149         /// Break
150         /// </summary>
151         /// <param name="forState"></param>
152         public void Break(object forState)
153         {
154             this.InternalBreakFor(forState, OpCodes.Br);
155         }
156 
157         /// <summary>
158         /// IfTrueBreak
159         /// </summary>
160         /// <param name="forState"></param>
161         public void IfTrueBreak(object forState)
162         {
163             this.InternalBreakFor(forState, OpCodes.Brtrue);
164         }       
165 
166         /// <summary>
167         /// IfFalseBreak
168         /// </summary>
169         /// <param name="forState"></param>
170         public void IfFalseBreak(object forState)
171         {
172             this.InternalBreakFor(forState, OpCodes.Brfalse);
173         }
174       
175 
176         /// <summary>
177         /// InternalBreakFor:Break
178         /// </summary>
179         /// <param name="userForState"></param>
180         /// <param name="branchInstruction"></param>
181         public void InternalBreakFor(object userForState, OpCode branchInstruction)
182         {
183             foreach (object obj2 in this.blockStack)
184             {
185                 ForState state = obj2 as ForState;
186                 if ((state != null) && (state == userForState))
187                 {  
188                      //定义EndLabel
189                     if (!state.RequiresEndLabel)
190                     {
191                         state.EndLabel = this.DefineLabel();
192                         state.RequiresEndLabel = true;
193                     }
194                     this.ilGen.Emit(branchInstruction, state.EndLabel);
195                     break;
196                 }
197             }
198         }

方法:

方法定义
 1        /// <summary>
 2         /// BeginMethod
 3         /// </summary>
 4         /// <param name="methodName"></param>
 5         /// <param name="delegateType"></param>
 6         public void BeginMethod(string methodName, Type delegateType)
 7         {
 8             Check.Require(this.methodOrConstructorBuilder == null, "BeginMethod() could not be called in this context.");
 9             Check.Require(methodName, "methodName", Check.NotNullOrEmpty);
10             Check.Require(delegateType, "delegateType");
11             //通过Invoke方法 来获取参数类型 及返回类型
12             MethodInfo method = delegateType.GetMethod("Invoke");
13             ParameterInfo[] parameters = method.GetParameters();
14             Type[] argTypes = new Type[parameters.Length];
15             for (int i = 0; i < parameters.Length; i++)
16             {
17                 argTypes[i] = parameters[i].ParameterType;
18             }
19             this.BeginMethod(method.ReturnType, methodName, argTypes);
20             this.delegateType = delegateType;
21         }
22 
23         /// <summary>
24         /// BeginMethod
25         /// </summary>
26         /// <param name="returnType"></param>
27         /// <param name="methodName"></param>
28         /// <param name="argTypes"></param>
29         private void BeginMethod(Type returnType, string methodName, params Type[] argTypes)
30         {   
31             //Emit 构建方法的一种
32             //对于定义整个类:可以参考另一种方式  typeBuilder.DefineMethod(targetMethod.Name, MethodAttributes.Public|MethodAttributes.Virtual, targetMethod.ReturnType, paramType);
33             //定义方法体  returnType methodName(argTypes){  }
34             this.dynamicMethod = new DynamicMethod(methodName, returnType, argTypes, serializationModule, true);
35             //获取方法体:写入流
36             this.ilGen = this.dynamicMethod.GetILGenerator();// this.ilGen代表当前方法上下文,所以Ldarg加载的是当前方法的。 在当前类里面,存于this.argList
37             this.methodEndLabel = this.ilGen.DefineLabel();
38             this.blockStack = new Stack();
39             this.argList = new ArrayList();
40             for (int i = 0; i < argTypes.Length; i++)
41             {
42                 this.argList.Add(new ArgBuilder(i, argTypes[i]));
43             }
44         }
45 
46 
47         /// <summary>
48         /// EndMethod
49         /// </summary>
50         /// <returns></returns>
51         public Delegate EndMethod()
52         {
53             Check.Require(this.methodOrConstructorBuilder == null, "EndMethod() could not be called in this context.");
54             //在此之前,通过this.ilGen添加操作代码,最后生成委托    
55 
56             //要返回的参数,现在在堆栈顶部
57             this.MarkLabel(this.methodEndLabel);
58             this.Ret();
59             Delegate delegate2 = null;
60             delegate2 = this.dynamicMethod.CreateDelegate(this.delegateType);
61 
62             //清空
63             this.dynamicMethod = null;
64             this.delegateType = null;
65             this.ilGen = null;
66             this.blockStack = null;
67             this.argList = null;
68             return delegate2;
69         }
70 
71         /// <summary>
72         /// IgnoreReturnValue
73         /// </summary>
74         public void IgnoreReturnValue()
75         {
76             this.Pop();
77         }
78 
79         /// <summary>
80         ///  Ret 从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。
81         ///  Do1: 从被调用方的计算堆栈中弹出返回值。
82         ///  Do2:将步骤 1 中获取的返回值推送到调用方的计算堆栈中。
83         /// </summary>
84         public void Ret()
85         {
86             this.ilGen.Emit(OpCodes.Ret);
87         } 
方法调用
  1    /// <summary>
  2         /// Call 调用由传递的方法说明符指示的方法。
  3         /// </summary>
  4         /// <param name="ctor"></param>
  5         public void Call(ConstructorInfo ctor)
  6         {
  7             Check.Require(ctor, "ctor");
  8 
  9             this.ilGen.Emit(OpCodes.Call, ctor);
 10         }
 11 
 12         /// <summary>
 13         /// Call 调用由传递的方法说明符指示的方法。
 14         /// </summary>
 15         /// <param name="methodInfo"></param>
 16         public void Call(MethodInfo methodInfo)
 17         {
 18             Check.Require(methodInfo, "methodInfo");
 19 
 20             if (methodInfo.IsVirtual)
 21             {
 22                 this.ilGen.Emit(OpCodes.Callvirt, methodInfo);
 23             }
 24             else if (methodInfo.IsStatic)
 25             {
 26                 this.ilGen.Emit(OpCodes.Call, methodInfo);
 27             }
 28             else
 29             {
 30                 this.ilGen.Emit(OpCodes.Call, methodInfo);
 31             }
 32         }
 33 
 34         /// <summary>
 35         /// Call
 36         /// </summary>
 37         /// <param name="thisObj"></param>
 38         /// <param name="methodInfo"></param>
 39         public void Call(object thisObj, MethodInfo methodInfo)
 40         {
 41             Check.Require(thisObj, "thisObj");
 42             Check.Require(methodInfo, "methodInfo");
 43 
 44             this.VerifyParameterCount(methodInfo, 0);
 45             this.LoadThis(thisObj, methodInfo);
 46             this.Call(methodInfo);
 47         }
 48 
 49         /// <summary>
 50         /// Call
 51         /// </summary>
 52         /// <param name="thisObj"></param>
 53         /// <param name="methodInfo"></param>
 54         /// <param name="param1"></param>
 55         public void Call(object thisObj, MethodInfo methodInfo, object param1)
 56         {
 57             Check.Require(thisObj, "thisObj");
 58             Check.Require(methodInfo, "methodInfo");
 59 
 60             this.VerifyParameterCount(methodInfo, 1);
 61             //Loadthis:加载this对象,并且转换为方法声明类的类型
 62             this.LoadThis(thisObj, methodInfo);
 63             //LoadParam:加载参数,并且转换为方法参数所定义的类型
 64             this.LoadParam(param1, 1, methodInfo);
 65             this.Call(methodInfo);
 66         }
 67 
 68         /// <summary>
 69         /// Call
 70         /// </summary>
 71         /// <param name="thisObj"></param>
 72         /// <param name="methodInfo"></param>
 73         /// <param name="param1"></param>
 74         /// <param name="param2"></param>
 75         public void Call(object thisObj, MethodInfo methodInfo, object param1, object param2)
 76         {
 77             Check.Require(thisObj, "thisObj");
 78             Check.Require(methodInfo, "methodInfo");
 79 
 80             this.VerifyParameterCount(methodInfo, 2);
 81             this.LoadThis(thisObj, methodInfo);
 82             this.LoadParam(param1, 1, methodInfo);
 83             this.LoadParam(param2, 2, methodInfo);
 84             this.Call(methodInfo);
 85         }
 86 
 87         /// <summary>
 88         /// Call
 89         /// </summary>
 90         /// <param name="thisObj"></param>
 91         /// <param name="methodInfo"></param>
 92         /// <param name="param1"></param>
 93         /// <param name="param2"></param>
 94         /// <param name="param3"></param>
 95         public void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3)
 96         {
 97             Check.Require(thisObj, "thisObj");
 98             Check.Require(methodInfo, "methodInfo");
 99 
100             this.VerifyParameterCount(methodInfo, 3);
101             this.LoadThis(thisObj, methodInfo);
102             this.LoadParam(param1, 1, methodInfo);
103             this.LoadParam(param2, 2, methodInfo);
104             this.LoadParam(param3, 3, methodInfo);
105             this.Call(methodInfo);
106         }
107 
108         /// <summary>
109         /// Call
110         /// </summary>
111         /// <param name="thisObj"></param>
112         /// <param name="methodInfo"></param>
113         /// <param name="param1"></param>
114         /// <param name="param2"></param>
115         /// <param name="param3"></param>
116         /// <param name="param4"></param>
117         public void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4)
118         {
119             Check.Require(thisObj, "thisObj");
120             Check.Require(methodInfo, "methodInfo");
121 
122             this.VerifyParameterCount(methodInfo, 4);
123             this.LoadThis(thisObj, methodInfo);
124             //LoadParam:将参数变量转换成 方法中第N个参数的类型,加载到堆栈
125             this.LoadParam(param1, 1, methodInfo);
126             this.LoadParam(param2, 2, methodInfo);
127             this.LoadParam(param3, 3, methodInfo);
128             this.LoadParam(param4, 4, methodInfo);
129             this.Call(methodInfo);
130         }
131 
132         /// <summary>
133         /// Call
134         /// </summary>
135         /// <param name="thisObj"></param>
136         /// <param name="methodInfo"></param>
137         /// <param name="param1"></param>
138         /// <param name="param2"></param>
139         /// <param name="param3"></param>
140         /// <param name="param4"></param>
141         /// <param name="param5"></param>
142         public void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4, object param5)
143         {
144             Check.Require(thisObj, "thisObj");
145             Check.Require(methodInfo, "methodInfo");
146 
147             this.VerifyParameterCount(methodInfo, 5);
148             this.LoadThis(thisObj, methodInfo);
149             this.LoadParam(param1, 1, methodInfo);
150             this.LoadParam(param2, 2, methodInfo);
151             this.LoadParam(param3, 3, methodInfo);
152             this.LoadParam(param4, 4, methodInfo);
153             this.LoadParam(param5, 5, methodInfo);
154             this.Call(methodInfo);
155         }
156 
157         /// <summary>
158         /// Call
159         /// </summary>
160         /// <param name="thisObj"></param>
161         /// <param name="methodInfo"></param>
162         /// <param name="param1"></param>
163         /// <param name="param2"></param>
164         /// <param name="param3"></param>
165         /// <param name="param4"></param>
166         /// <param name="param5"></param>
167         /// <param name="param6"></param>
168         public void Call(object thisObj, MethodInfo methodInfo, object param1, object param2, object param3, object param4, object param5, object param6)
169         {
170             Check.Require(thisObj, "thisObj");
171             Check.Require(methodInfo, "methodInfo");
172 
173             this.VerifyParameterCount(methodInfo, 6);
174             this.LoadThis(thisObj, methodInfo);
175             this.LoadParam(param1, 1, methodInfo);
176             this.LoadParam(param2, 2, methodInfo);
177             this.LoadParam(param3, 3, methodInfo);
178             this.LoadParam(param4, 4, methodInfo);
179             this.LoadParam(param5, 5, methodInfo);
180             this.LoadParam(param6, 6, methodInfo);
181             this.Call(methodInfo);
182         }
183 
184 
185         /// <summary>
186         /// VerifyParameterCount
187         /// </summary>
188         /// <param name="methodInfo"></param>
189         /// <param name="expectedCount"></param>
190         public void VerifyParameterCount(MethodInfo methodInfo, int expectedCount)
191         {
192             Check.Require(methodInfo, "methodInfo");
193 
194             if (methodInfo.GetParameters().Length != expectedCount)
195             {
196                 throw new Exception("ParameterCountMismatch");
197             }
198         }
原文地址:https://www.cnblogs.com/AspDotNetMVC/p/2943172.html