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         }

 

 

 

你可能感兴趣的:(generator)