zoukankan      html  css  js  c++  java
  • 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         }
  • 相关阅读:
    使用AsyncTask简单的文件遍历
    如何创建黑名单
    关于PopupMenu的用法
    联系人的搜索和添加
    php获取真实IP地址
    socket.io获取客户端的IP地址(修正官方1.0.4版本BUG)
    ubuntu下安装bind9
    install source nginx 1.6.0
    在Ubuntu下的samba实现
    买了新硬盘,给ESXI的虚拟机挂进真实硬盘。
  • 原文地址:https://www.cnblogs.com/AspDotNetMVC/p/2943172.html
Copyright © 2011-2022 走看看