ILGen.cs :  » Aspect-Oriented-Frameworks » Runtime-Assembly-Instrumentation-Library » rail » MSIL » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Aspect Oriented Frameworks » Runtime Assembly Instrumentation Library 
Runtime Assembly Instrumentation Library » rail » MSIL » ILGen.cs
/*
  The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); 
  you may not use this file except in compliance with the License. You may obtain a copy of the License at 
  http://www.mozilla.org/MPL/ 
  Software distributed under the License is distributed on an "AS IS" basis, 
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language 
  governing rights and limitations under the License. 

  The Original Code is RAIL(Runtime Assembly Instrumentation Library) Alpha Version.
  The Initial Developer of the Original Code is University of Coimbra,
  Computer Science Department, Dependable Systems Group. Copyright (C) University of Coimbra. 
  All Rights Reserved.  
*/
using System;
using System.Reflection.Emit;
using System.Diagnostics;
using System.Reflection;
using System.Collections;
using Rail.Reflect;


namespace Rail.MSIL{
  /// <summary>
  /// 
  /// </summary>
  /// <remarks>
  ///  Guidelines:
  ///  
  ///  <list type="numbered">
  ///  <item> Instructions that have an .un (unsigned or unordered version) are 
  ///   represented only by one method, which takes a boolean parameter called signed.
  ///   For instance: <code>public void Add_Ovf(bool signed);</code>
  ///  </item>
  ///  
  ///  <item> The calli opcode/EmitCalli method is not supported. Use the underlying
  ///  ILGenerator to emit it.
  ///  </item>
  ///  
  ///  </list>
  ///    
  /// </remarks>
  public sealed class ILFactory 
  {
    #region Base Instructions        
    /*
     * This includes: 
     * 
     * add, add.ovf, and, arglist, beq, bge, bge.un, ble, ble.un
     * blt, blt.un, bne.un, br, break, brfalse, brtrue, call, calli, ceq, cgt,
     * cgt.un, ckfinite, clt, clt.un, conv, conv.ovf.<totype>, conv.ovf.<totype>.un,
     * cpblk, div, div.un, dup, endfilter, endfinally, initblk, jmp, jmpi, ldarg,
     * ldarga, ldc, ldftn, ldind, ldloc, ldloca, ldnull, leave, localloc, mul, mul.ovf,
     * neg, nop, not, or, pop, rem, rem.un, ret, shl, shr, shr.un, starg, stind, stloc, 
     * sub, sub.ovf, switch, tail, unaligned, volatile, xor
     * 
     * A lot!!!
     */    

    /// <summary>
    /// add - add numeric values
    /// <code>value1, value2 -> result</code>
    /// </summary>
    public static Instruction Add() 
    {
      return new ILNone(OpCodes.Add);      
    }

    /// <summary>
    /// add.ovf.&lt;signed&gt; - add integer values with overflow check
    /// <code>value1, value2 -> result</code>
    /// </summary>
    /// <param name="signed">Whether add.ovf or add.ovf.un should be used</param>
    public static Instruction Add_Ovf(bool signed) 
    {
      OpCode op = signed ? OpCodes.Add_Ovf : OpCodes.Add_Ovf_Un;
      return new ILNone(op);      
    }

    /// <summary>
    /// and - bitwise AND
    /// <code>value1, value2 -> result</code>
    /// </summary>
    public static Instruction And() 
    {
      return new ILNone(OpCodes.And);
    }

    /// <summary>
    /// arglist - get argument list    
    /// <code> -> </code>    
    /// </summary>
    public static Instruction Arglist() 
    {      
      return new ILNone(OpCodes.Arglist);
    }

    /// <summary>
    /// beq.&lt;length&gt;  branch on equal
    /// <code>value1, value2 -> </code>    
    /// </summary>
    /// <param name="target">The target instruction</param>
    public static Instruction Beq(Instruction target) 
    {      
      return new ILBranch(OpCodes.Beq, target);
    }

    /// <summary>
    /// bge.&lt;length&gt;  branch on greater than or equal to
    /// bge.un.&lt;length&gt;  branch on greater/equal, unsigned or unordered
    /// <code>value1, value2 -> </code>    
    /// </summary>
    /// <param name="signed">Whether to use bge or bge.un</param>
    /// <param name="target">The target instruction</param>
    public static Instruction Bge(bool signed, Instruction target) 
    {      
      OpCode op = signed ? OpCodes.Bge: OpCodes.Bge_Un;
      return new ILBranch(op, target);
    }

    /// <summary>
    /// bgt.&lt;length&gt;  branch on greater than
    /// bgt.un.&lt;length&gt;  branch on greater than, unsigned or unordered
    /// <code>value1, value2 -> </code>
    /// </summary>
    /// <param name="signed">If the instruction is signed</param>
    /// <param name="target">The target instruction</param>
    public static Instruction Bgt(bool signed, Instruction target) 
    {
      OpCode op = signed ? OpCodes.Bgt : OpCodes.Bgt_Un;
      return new ILBranch(op, target);
    }

    /// <summary>
    /// ble._  branch on less than or equal to
    /// ble.un._  branch on less/equal, unsigned or unordered
    /// <code>value1, value2 -> </code>
    /// </summary>
    /// <param name="signed">If the instruction is signed</param>
    /// <param name="target">the target instruction</param>
    public static Instruction Ble(bool signed, Instruction target) 
    {
      OpCode op = signed ? OpCodes.Ble :OpCodes.Ble_Un;
      return new ILBranch(op, target);
    }

    /// <summary>
    /// blt._  branch on less than
    /// blt.un._  branch on less than, unsigned or unordered
    /// <code>value1, value2 -> </code>
    /// </summary>
    /// <param name="signed">If the instruction is signed</param>
    /// <param name="target">The target instruction</param>
    public static Instruction Blt(bool signed, Instruction target) 
    {
      OpCode op = signed ? OpCodes.Blt :OpCodes.Blt_Un;
      return new ILBranch(op, target);
    }

    /// <summary>
    /// bne.un  branch on not equal or unordered
    /// <code> value1, value2 ->  </code>
    /// </summary>
    /// <param name="target"></param>
    public static Instruction Bne_Un(Instruction target) 
    {      
      return new ILBranch(OpCodes.Bne_Un, target);
    }

    /// <summary>
    /// br._  unconditional branch
    /// <code> -> </code>
    /// </summary>
    /// <param name="target"></param>
    public static Instruction Br(Instruction target) 
    {      
      return new ILBranch(OpCodes.Br, target);
    }

    /// <summary>
    /// Unconditional branch
    /// </summary>
    /// <param name="target"></param>
    /// <returns></returns>
    public static Instruction BrS(Instruction target)
    {
      return new ILBranch(OpCodes.Br_S,target);
    }

    /// <summary>
    /// break  breakpoint instruction
    /// <code> -> </code>
    /// </summary>
    /// <param name="target"></param>
    public static Instruction Break(Instruction target) 
    {
      return new ILBranch(OpCodes.Break, target);
    }

    /// <summary>
    /// brfalse._ - branch on false, null, or zero
    /// brtrue._ - branch on non-false or non-null
    /// <code>value -> </code>
    /// </summary>
    /// <param name="condition">True for <code>brtrue</code>, false for <code>brfalse</code></param>
    /// <param name="target">The target instruction</param>
    public static Instruction Br(bool condition, Instruction target) 
    {      
      OpCode op = condition ? OpCodes.Brtrue : OpCodes.Brfalse;      
      return new ILBranch(op, target);
    }

    /// <summary>
    /// brfalse.S_ - branch on false, null, or zero
    /// brtrue.S_ - branch on non-false or non-null
    /// <code>value -> </code>
    /// </summary>
    /// <param name="condition">True for <code>brtrue</code>, false for <code>brfalse</code></param>
    /// <param name="target">The target instruction</param>
    public static Instruction BrS(bool condition, Instruction target) 
    {      
      OpCode op = condition ? OpCodes.Brtrue_S : OpCodes.Brfalse_S;      
      return new ILBranch(op, target);
    }

    /// <summary>
    /// call  call a method
    /// callvirt  call a method associated, at runtime, with an object
    /// <code> obj, arg1, arg2  argn -> retVal (not always returned)</code>
    /// </summary>
    /// <remarks>
    /// The obj argument is only necessary if calling an instance or virtual 
    /// method.
    /// </remarks>
    /// <param name="callVirtual">Whether to call the method virtually or statically.</param>    
    /// <param name="method">The method to be called. May be a ConstructorInfo 
    /// or a MethodInfo.</param>
    public static Instruction Call(bool callVirtual, RMethodBase method) 
    {
      OpCode op = callVirtual ? OpCodes.Callvirt : OpCodes.Call;      
      return new ILMethod(op, method);             
    }

    /// <summary>
    /// ceq - compare equal
    ///  <code>value1, value2 -> result</code>
    /// </summary>    
    public static Instruction Ceq() 
    {
      return new ILNone(OpCodes.Ceq);
    }

    /// <summary>
    /// cgt - compare greater than
    /// cgt.un - compare greater than, unsigned or unordered
    /// <code> value1, value2 -> result</code>
    /// </summary>
    public static Instruction Cgt(bool signed) 
    {
      return new ILNone(signed ? OpCodes.Cgt : OpCodes.Cgt_Un);
    }

    /// <summary>
    /// <p>ckfinite  check for a finite real number</p>
    /// <code> value -> value</code>
    /// </summary>
    public static Instruction Ckfinite() 
    {
      return new ILNone(OpCodes.Ckfinite);
    }

    /// <summary>
    /// clt - compare less than
    /// clt.un - compare less than, unsigned or unordered 
    /// <code>value1, value2 -> result</code>
    /// </summary>
    /// <param name="signed">Whether to use clt or clt.un</param>
    public static Instruction Clt(bool signed) 
    {
      OpCode op = signed ? OpCodes.Clt : OpCodes.Clt_Un;      
      return new ILNone(op);
    }

    /// <summary>
    /// conv._to type - data conversion
    /// <code> value -> result</code>
    /// </summary>
    /// <remarks>
    /// The given type may be one of the primitive types and IntPtr or UIntPtr.
    /// To emit the <code>conv.r.un</code> instruction use the internal 
    /// <code>ILGenerator</code>
    /// </remarks>
    /// <param name="type">The type for the conversion</param>
    public static Instruction Conv(Type type) 
    {
      CLROperandType op = (CLROperandType) typeToCLROperand[type];
      if (op == null) 
      {
        throw new ArgumentException("Only CLR types are allowed. Found: " + type);
      }
      
      if (Object.ReferenceEquals(op.Conv, OpCodes.Nop))
        throw new InvalidProgramException();
      return new ILNone(op.Conv);
    }

    /// <summary>
    /// conv.ovf._to_type - data conversion with overflow detection
    /// conv.ovf._to_type.un  unsigned data conversion with overflow detection
    /// <code> value -> result</code>
    /// </summary>
    /// <remarks>
    /// The given type may be one of the primitive types including 
    /// IntPtr and UIntPtr, but excluding floating point values.
    /// <code>ILGenerator</code>
    /// </remarks>
    /// <param name="signed">Whether to use <code>conv_ovf</code> or conv.ovf._type.un</param>
    /// <param name="type"></param>
    public static Instruction Conv_Ovf(bool signed, Type type) 
    {
      // floating points values don't have conversion operators with overflow checking
      if (type != typeof(System.Single) && type != typeof(System.Double)) 
      {
        CLROperandType opType = (CLROperandType)typeToCLROperand[type];        
        if (opType != null) 
        {
          OpCode opCode;
          opCode = signed ? opType.Conv_Ovf : opType.Conv_Ovf_Un;          
          //Debug.Assert(!Object.ReferenceEquals(opCode, OpCodes.Nop));          
          if (Object.ReferenceEquals(opCode, OpCodes.Nop))
            throw new InvalidProgramException();
          return new ILNone(opCode);          
        }
      }
      throw new ArgumentException("Valid types: Byte, SByte, Int16/32/64, Uint16/32/64, IntPtr, UIntPtr. Found: " + type);
    }

    /// <summary>
    /// cpblk - copy data from memory to memory
    /// <code>destaddr, srcaddr, size ->  </code>   
    /// </summary>
    public static Instruction Cpblk()
    {
      return new ILNone(OpCodes.Cpblk);
    }

    /// <summary>
    /// div - divide values
    /// div.un - divide integer values, unsigned
    /// <code>value1, value2 -> result</code>
    /// </summary>
    /// <param name="signed">Whether to emit div or div.un</param>
    public static Instruction Div(bool signed)
    {
      OpCode op = signed ? OpCodes.Div : OpCodes.Div_Un;
      return new ILNone(op);
    }

    /// <summary>
    /// dup  duplicate the top value of the stack
    /// <code>value -> value, value</code>    
    /// </summary>    
    public static Instruction Dup()
    {      
      return new ILNone(OpCodes.Dup);
    }

    /// <summary>
    /// endfilter  end filter clause of SEH
    /// <code>value ->  </code>    
    /// </summary>    
    public static Instruction Endfilter()
    {      
      return new ILNone(OpCodes.Endfilter);
    }

    /// <summary>
    /// endfinally  end finally clause of an exception block
    /// <code> -> </code>
    /// </summary>    
    public static Instruction Endfinaly()
    {
      return new ILNone(OpCodes.Endfinally);
    }

    /// <summary>
    /// initblk - initialize a block of memory to a value
    /// <code> addr, value, size -> </code>
    /// </summary>    
    public static Instruction Initblk()
    {
      return new ILNone(OpCodes.Initblk);
    }

    /// <summary>
    /// jmp  jump to method
    /// <code> -> </code>
    /// </summary>    
    public static Instruction Jmp(RMethodBase method)
    {
      return new ILMethod(OpCodes.Jmp, method);
    }

    /// <summary>
    /// ldarg.length - load argument onto the stack
    /// <code> -> value </code>
    /// </summary>
    /// <remarks>
    /// </remarks>
    /// <param name="parameter">The parameter to be loaded.</param>
    public static Instruction Ldarg(RParameter parameter) 
    {      
      return new ILArgument(OpCodes.Ldarg, parameter);      
    }

    /// <summary>
    /// ldarga.length - load an argument address
    /// <code> -> address of argument number argNum</code>    
    /// </summary>
    /// <param name="parameter"></param>
    public static Instruction Ldarga(RParameter parameter) 
    {
      return new ILArgument(OpCodes.Ldarga, parameter);
      
    }

    /// <summary>
    /// ldc.i4.x - load numeric constant    
    /// <code> -> num</code>    
    /// </summary>
    /// <param name="iConst"></param>
    public static Instruction Ldc(int iConst) 
    {      
      switch(iConst)
      {
        case 0:
          return new ILNone(OpCodes.Ldc_I4_0);
        case 1:
          return new ILNone(OpCodes.Ldc_I4_1);
        case 2:
          return new ILNone(OpCodes.Ldc_I4_2);
        case 3:
          return new ILNone(OpCodes.Ldc_I4_3);
        case 4:
          return new ILNone(OpCodes.Ldc_I4_4);
        case 5:
          return new ILNone(OpCodes.Ldc_I4_5);
        case 6:
          return new ILNone(OpCodes.Ldc_I4_6);
        case 7:
          return new ILNone(OpCodes.Ldc_I4_7);
        case 8:
          return new ILNone(OpCodes.Ldc_I4_8);
        default:
          return new ILOperandI4(OpCodes.Ldc_I4, iConst);
      }
    }

    /// <summary>
    /// ldc.i8 - load numeric constant
    /// <code> -> num</code>    
    /// </summary>
    /// <param name="lConstant"></param>
    public static Instruction Ldc(Int64 lConstant) 
    {
      return new ILOperandI8(OpCodes.Ldc_I8, lConstant);
    }

    /// <summary>
    /// ldc.r8 - load numeric constant
    /// <code> -> num</code>    
    /// </summary>
    /// <param name="fConstant"></param>
    public static Instruction Ldc(Double fConstant) 
    {      
      return new ILOperandR8(OpCodes.Ldc_R8, fConstant);      
    }

    /// <summary>
    /// ldc.r4 - load numeric constant
    /// <code> -> num</code>
    /// </summary>
    /// <param name="fConstant"></param>
    public static Instruction Ldc(Single fConstant) 
    {
      return new ILOperandR4(OpCodes.Ldc_R4, fConstant);
    }

    /// <summary>
    /// ldftn - load method pointer
    /// <code> -> ftn</code>    
    /// </summary>
    public static Instruction Ldftn(RMethodBase mi) 
    {
      return new ILMethod(OpCodes.Ldftn, mi);
    }

    /// <summary>
    /// ldind._type_ - load value indirect onto the stack    
    /// <code>addr -> value</code> 
    /// </summary>
    /// <remarks>
    /// If <code>t</code> is not one of the CLR primitive types then 
    /// it must be System.Object. In this case, a <code>ldind.ref</code> 
    /// opcode is pushed onto the stack. Otherwise, an exception is raised.
    /// </remarks>
    /// <param name="t"></param>
    public static Instruction Ldind(Type t) 
    {
      CLROperandType op = (CLROperandType)typeToCLROperand[t];
      if (op==null) 
      {                          
        throw new ArgumentException("Type must be one of the CLR primitive types or System.Object. Found: " + t);        
      } 
      else 
      {
        
        if (Object.ReferenceEquals(op.Ldind, OpCodes.Nop))
          throw new InvalidProgramException();
        return new ILNone(op.Ldind);
      }
    }

    /// <summary>
    /// ldloc - load local variable onto the stack
    /// <code> -> value</code> 
    /// </summary>    
    /// <param name="local"></param>
    public static Instruction Ldloc(LocalVariable local) 
    {
      return new ILLocalVariable(OpCodes.Ldloc, local);
    }

    /// <summary>
    /// ldloca._ - load local variable address
    /// <code> -> address</code> 
    /// </summary>    
    /// <param name="local"></param>
    public static Instruction Ldloca(LocalVariable local) 
    {      
      return new ILLocalVariable(OpCodes.Ldloca, local);            
    }

    /// <summary>
    /// ldnull  load a null pointer
    /// <code> -> null value</code> 
    /// </summary>        
    public static Instruction Ldnull() 
    {
      return new ILNone(OpCodes.Ldnull);
    }

    /// <summary>
    /// leave._  exit a protected region of code
    /// <code> -> </code> 
    /// </summary>    
    /// <param name="target">The target instruction</param>
    public static Instruction Leave(Instruction target) 
    {
      return new ILBranch(OpCodes.Leave, target);
    }

    /// <summary>
    /// localloc  allocate space in the local dynamic memory pool
    /// <code> size -> address </code> 
    /// </summary>        
    public static Instruction Localloc() 
    {
      return new ILNone(OpCodes.Localloc);
    }

    /// <summary>
    /// mul - multiply values
    /// <code> value1, value2 -> result </code>
    /// </summary>        
    public static Instruction Mul() 
    {
      return new ILNone(OpCodes.Mul);
    }

    /// <summary>
    /// mul.ovf - Multiply signed integer values. Signed result must fit in same size
    /// mul.ovf.un - Multiply unsigned integer values. Unsigned result must fit in same size    ///     
    /// <code> value1, value2 -> result </code>
    /// </summary>            
    public static Instruction Mul_Ovf(bool signed) 
    {
      OpCode op = signed ? OpCodes.Mul_Ovf : OpCodes.Mul_Ovf_Un;
      return new ILNone(op);
    }
    
    /// <summary>
    /// neg - negate
    /// <code> value -> result </code>
    /// </summary>        
    public static Instruction Neg() 
    {
      return new ILNone(OpCodes.Neg);
    }

    /// <summary>
    /// nop  no operation
    /// <code> -> </code>
    /// </summary>        
    public static Instruction Nop() 
    {
      return new ILNone(OpCodes.Nop);
    }

    /// <summary>
    /// not - bitwise complement
    /// <code> value -> result </code>
    /// </summary>        
    public static Instruction Not() 
    {
      return new ILNone(OpCodes.Not);
    }

    /// <summary>
    /// or - bitwise OR
    /// <code> value1, value2 -> result </code>
    /// </summary>        
    public static Instruction Or() 
    {
      return new ILNone(OpCodes.Or);
    }

    /// <summary>
    /// pop  remove the top element of the stack
    /// <code> value -> </code>
    /// </summary>        
    public static Instruction Pop() 
    {
      return new ILNone(OpCodes.Pop);
    }

    /// <summary>
    /// rem - compute remainder
    /// rem.un - compute integer remainder, unsigned
    /// <code> value1, value2 -> result </code>
    /// </summary>        
    public static Instruction Rem(bool signed) 
    {
      OpCode op = signed ? OpCodes.Rem : OpCodes.Rem_Un;
      return new ILNone(op);
    }

    /// <summary>
    /// ret  return from method 
    /// <code> retVal on callee evaluation stack (not always present) 
    /// -> retVal on caller evaluation stack (not always present) </code>
    /// </summary>        
    public static Instruction Ret() 
    {      
      return new ILNone(OpCodes.Ret);
    }

    /// <summary>
    /// shl - shift integer left 
    /// <code> value, shiftAmount -> result </code>
    /// </summary>        
    public static Instruction Shl() 
    {      
      return new ILNone(OpCodes.Shl);
    }

    /// <summary>
    /// shr - shift integer right
    /// shr.un - shift integer right, unsigned
    /// <code> value, shiftAmount -> result </code>
    /// </summary>        
    public static Instruction Shr(bool signed) 
    {
      OpCode op = signed ? OpCodes.Shr : OpCodes.Shr_Un;
      return new ILNone(op);
    }

    /// <summary>
    /// starg._ - store a value in an argument slot
    /// <code> value -> </code> 
    /// </summary>    
    /// <param name="arg"></param>
    public static Instruction Starg(RParameter arg) 
    {
      return new ILArgument(OpCodes.Starg, arg);            
    }


    /// <summary>
    /// stind._type - store value indirect from stack
    /// <code>addr, value ->  </code> 
    /// </summary>
    /// <remarks>
    /// If <code>t</code> is not one of the CLR primitive types then 
    /// it must be System.Object. In this case, a <code>ldind.ref</code> 
    /// opcode is pushed onto the stack. Otherwise, an exception is raised.
    /// </remarks>
    /// <param name="t"></param>
    public static Instruction Stind(Type t) 
    {      
      CLROperandType op = (CLROperandType)typeToCLROperand[t];
      if (op==null) 
      {        
        throw new ArgumentException("Type must be one of the CLR primitive types or System.Object. Found: " + t);        
      } 
      else 
      {
        
        if (Object.ReferenceEquals(op.Stind, OpCodes.Nop))
          throw new InvalidProgramException();
        return new ILNone(op.Stind);
      }
    }

    /// <summary>
    /// stloc - pop value from stack to local variable
    /// <code> value -> </code> 
    /// </summary>        
    public static Instruction Stloc(LocalVariable local) 
    {      
      return new ILLocalVariable(OpCodes.Stloc, local);      
    }

    /// <summary>
    /// sub - subtract numeric values 
    /// <code> value1, value2 -> result </code>
    /// </summary>        
    public static Instruction Sub() 
    {      
      return new ILNone(OpCodes.Sub);
    }

    /// <summary>
    /// sub.ovf - Subtract native int from a native int. Signed result must fit in same size
    /// sub.ovf.un - Subtract native unsigned int from a native unsigned int. Unsigned result must fit in same size
    /// <code> value, shiftAmount -> result </code>
    /// </summary>        
    public static Instruction Sub_Ovf(bool signed) 
    {
      OpCode op = signed ? OpCodes.Sub_Ovf : OpCodes.Sub_Ovf_Un;
      return new ILNone(op);
    }


    /// <summary>
    /// switch  table switch on value
    /// <code> value -> </code>
    /// </summary>        
    /// <param name="targets">The jump points for this switch</param>
    public static Instruction Switch(Instruction[] targets) 
    {
      return new ILSwitch(OpCodes.Switch, targets);
    }

    /// <summary>
    /// xor - bitwise XOR 
    /// <code> value1, value2 -> result </code>
    /// </summary>        
    public static Instruction Xor() 
    {      
      return new ILNone(OpCodes.Xor);
    }
    #endregion

    
    public static Instruction BeginExceptionBlock (ExceptionBlock eb) {
      return new ILVirtualException(eb, true);
    }

    public static Instruction EndExceptionBlock (ExceptionBlock eb) {
      return new ILVirtualException(eb, false);
    }

    public static Instruction BeginFaultBlock (ExceptionBlock eb) {
      return new ILVirtualException(eb, ExceptionHandlerType.Fault);
    }

    public static Instruction BeginFinallyBlock (ExceptionBlock eb) {
      return new ILVirtualException(eb, ExceptionHandlerType.Finally);
    }

    public static Instruction BeginExceptionBlock (ExceptionBlock eb, ExceptionHandler ch) {
      return new ILVirtualException(eb, ExceptionHandlerType.Catch, ch.ExceptionType);
    }

    #region Object model support instructions
    /// <summary>
    /// box  convert value type to object reference
    /// <code> valueType -> obj </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Box(RType t) 
    {      
      return new ILType(OpCodes.Box, t);
    }

    /// <summary>
    /// castclass  cast an object to a class
    /// <code> obj1 -> obj2 </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Castclass(RType t) 
    {
      return new ILType(OpCodes.Castclass, t);
    }

    /// <summary>
    /// cpobj - copy a value type
    /// <code> destValObj, srcValObj ->  </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Cpobj(RType t) 
    {
      return new ILType(OpCodes.Cpobj, t);
    }

    /// <summary>
    /// initobj - initialize a value type
    /// <code> addrOfValObj ->  </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Initobj(RType t) 
    {
      return new ILType(OpCodes.Initobj, t);
    }
    
    /// <summary>
    /// isinst  test if an object is an instance of a class or interface
    /// <code> obj -> result  </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Isinst(RType t) 
    {
      return new ILType(OpCodes.Isinst, t);
    }
    
    /// <summary>
    /// ldelem._type  load an element of an array
    /// <code> array, index -> value</code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Ldelem(Type t) 
    {
      CLROperandType clrOp = (CLROperandType)typeToCLROperand[t];
      if (clrOp == null) 
      {
        throw new ArgumentException("Only CLR primitive types are allowed");
      } 
      else 
      {
        
        if (Object.ReferenceEquals(clrOp.Ldelem, OpCodes.Nop))
          throw new InvalidProgramException();
        return new ILNone(clrOp.Ldelem);
      }
    }

    /// <summary>
    /// ldelema  load address of an element of an array
    /// <code> array, index -> address </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Ldelema(RType t) 
    {
      return new ILType(OpCodes.Ldelema, t);
    }

    /// <summary>
    /// ldfld  load field of an object
    /// <code> obj -> value </code>
    /// </summary>
    /// <param name="fi"></param>
    public static Instruction Ldfld(RField fi) 
    {
      return new ILField(OpCodes.Ldfld, fi);
    }

    /// <summary>
    /// ldflda  load field address
    /// <code> obj -> address</code>
    /// </summary>
    /// <param name="fi"></param>
    public static Instruction Ldflda(RField fi) 
    {
      return new ILField(OpCodes.Ldflda, fi);
    }
    
    /// <summary>
    /// ldlen  load the length of an array
    /// <code> array -> length </code>
    /// </summary>    
    public static Instruction Ldlen() 
    {
      return new ILNone(OpCodes.Ldlen);
    }
    
    /// <summary>
    /// ldobj - copy value type to the stack
    /// <code> addrOfValObj -> valObj</code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Ldobj(RType t) 
    {
      return new ILType(OpCodes.Ldobj, t);
    }

    /// <summary>
    /// ldsfld  load static field of a class
    /// <code> -> value </code>
    /// </summary>
    /// <param name="fi"></param>
    public static Instruction Ldsfld(RField fi) 
    {
      return new ILField(OpCodes.Ldsfld, fi);
    }

    /// <summary>
    /// ldsflda  load static field address
    /// <code> -> address </code>
    /// </summary>
    /// <param name="fi"></param>
    public static Instruction Ldsflda(RField fi) 
    {
      return new ILField(OpCodes.Ldsflda, fi);
    }
    
    /// <summary>
    /// ldstr  load a literal string
    /// <code> -> string </code>
    /// </summary>
    /// <param name="str"></param>
    public static Instruction Ldstr(String str) 
    {
      return new ILString(OpCodes.Ldstr, str);
    }

    /// <summary>
    /// ldtoken - load the runtime representation of a metadata token
    /// <code> -> RuntimeHandle </code>
    /// </summary>
    /// <param name="mi"></param>
    public static Instruction Ldtoken(RMethod mi) 
    {
      return new ILToken(OpCodes.Ldtoken, mi);
    }

    /// <summary>
    /// ldtoken - load the runtime representation of a metadata token
    /// <code> -> RuntimeHandle </code>
    /// </summary>
    /// <param name="fi"></param>
    public static Instruction Ldtoken(RField fi) 
    {
      return new ILToken(OpCodes.Ldtoken, fi);
    }

    /// <summary>
    /// ldtoken - load the runtime representation of a metadata token
    /// <code> -> RuntimeHandle </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Ldtoken(RType t) 
    {
      return new ILToken(OpCodes.Ldtoken, t);
    }

    /// <summary>
    /// ldvirtftn - load a virtual method pointer
    /// <code> object -> ftn </code>
    /// </summary>
    /// <param name="mi"></param>
    public static Instruction Ldvirtftn(RMethodBase mi) 
    {
      return new ILMethod(OpCodes.Ldvirtftn, mi);
    }

    /// <summary>
    /// mkrefany  push a typed reference on the stack
    /// <code> ptr -> typedRef </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Mkrefany(RType t) 
    {
      return new ILType(OpCodes.Mkrefany, t);
    }

    /// <summary>
    /// newarr  create a zero-based, one-dimensional array
    /// <code> numElems -> array </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Newarr(RType t) 
    {
      return new ILType(OpCodes.Newarr, t);
    }

    /// <summary>
    /// newobj  create a new object
    /// <code> arg1,  argN -> obj </code>
    /// </summary>
    /// <param name="ct"></param>
    public static Instruction Newobj(RConstructor ct) 
    {
      return new ILMethod(OpCodes.Newobj, ct);
    }

    /// <summary>
    /// refanytype  load the type out of a typed reference
    /// <code> TypedRef -> type</code>
    /// </summary>    
    public static Instruction Refanytype() 
    {
      return new ILNone(OpCodes.Refanytype);
    }

    /// <summary>
    /// refanyval  load the address out of a typed reference
    /// <code> TypedRef -> address</code>
    /// </summary>    
    /// <param name="t"></param>
    public static Instruction Refanyval(RType t) 
    {
      return new ILType(OpCodes.Refanyval, t);
    }

    /// <summary>
    /// rethrow  rethrow the current exception
    /// <code> -> </code>
    /// </summary>    
    public static Instruction Rethrow() 
    {
      return new ILNone(OpCodes.Rethrow);
    }

    /// <summary>
    /// sizeof  load the size in bytes of a value type
    /// <code> -> size (4 bytes, unsigned) </code>
    /// </summary>    
    /// <param name="t">Must be a value type.</param>
    public static Instruction Sizeof(RType t) 
    {
      return new ILType(OpCodes.Sizeof, t);
    }

    /// <summary>
    /// stelem._type  store an element of an array
    /// <code> array, index, value -> </code>
    /// </summary>
    /// <param name="t"></param>
    public static Instruction Stelem(Type t) 
    {
      CLROperandType clrOp = (CLROperandType)typeToCLROperand[t];
      if (clrOp == null) 
      {
        throw new ArgumentException("Only CLR types are allowed");
      } 
      else 
      {
        
        if (Object.ReferenceEquals(clrOp.Stelem, OpCodes.Nop))
          throw new InvalidProgramException();
        return new ILNone(clrOp.Stelem);
      }
    }

    /// <summary>
    /// stfld  store into a field of an object
    /// <code> obj, value -> </code>
    /// </summary>    
    /// <param name="fi"></param>
    public static Instruction Stfld(RField fi) 
    {
      return new ILField(OpCodes.Stfld, fi);
    }

    /// <summary>
    /// stobj - store a value type from the stack into memory
    /// <code> addr, valObj -> </code>
    /// </summary>    
    /// <param name="t"></param>
    public static Instruction Stobj(RType t) 
    {
      return new ILType(OpCodes.Stobj, t);
    }
    
    /// <summary>
    /// stsfld  store a static field of a class
    /// <code> val -> </code>
    /// </summary>
    /// <param name="fi"></param>
    public static Instruction Stsfld(RField fi) 
    {
      return new ILField(OpCodes.Stsfld, fi);
    }
    
    /// <summary>
    /// throw  throw an exception
    /// <code> obj -> </code>
    /// </summary>        
    public static Instruction Throw() 
    {
      return new ILNone(OpCodes.Throw);
    }

    /// <summary>
    /// unbox  Convert boxed value type to its raw form
    /// <code> obj -> valueTypePtr</code>
    /// </summary>        
    /// <param name="t"></param>
    public static Instruction Unbox(RType t) 
    {
      return new ILType(OpCodes.Unbox, t);
    }
    #endregion

    #region Static helper methods
    static ILFactory() 
    {
      typeToCLROperand = new Hashtable(24);
      // Signed types
      typeToCLROperand[typeof(System.SByte)] = CLROperandType.I1;
      typeToCLROperand[typeof(System.Int16)] = CLROperandType.I2;
      typeToCLROperand[typeof(System.Int32)] = CLROperandType.I4;
      typeToCLROperand[typeof(System.Int64)] = CLROperandType.I8;
      // Unsigned types
      typeToCLROperand[typeof(System.Byte)] = CLROperandType.U1;
      typeToCLROperand[typeof(System.UInt16)] = CLROperandType.U2;
      typeToCLROperand[typeof(System.UInt32)] = CLROperandType.U4;
      typeToCLROperand[typeof(System.UInt64)] = CLROperandType.U8;
      // Floating point types
      typeToCLROperand[typeof(System.Single)] = CLROperandType.R4;
      typeToCLROperand[typeof(System.Double)] = CLROperandType.R8;
      // Native type
      typeToCLROperand[typeof(System.IntPtr)] = CLROperandType.I;
      typeToCLROperand[typeof(System.UIntPtr)] = CLROperandType.U;
      typeToCLROperand[typeof(System.Object)] = CLROperandType.O;
    }
    #endregion

    /// <summary>
    /// Define an instruction with the operanda as null
    /// </summary>
    /// <param name="ops">The opcode for the instructions</param>
    /// <returns>The instruction</returns>
    public static Instruction DefineInstruction(OpCode ops)
    {      
        if (OpCodes.Add.Value==ops.Value)
              return ILFactory.Add();
        if (OpCodes.Add_Ovf.Value==ops.Value)
          return ILFactory.Add_Ovf(false);
        if (OpCodes.And.Value==ops.Value)
          return ILFactory.And();
        if (OpCodes.Arglist.Value==ops.Value)
          return ILFactory.Arglist();
        if (OpCodes.Beq.Value==ops.Value ||
          OpCodes.Beq_S.Value==ops.Value)
          return ILFactory.Beq(null);
        if (OpCodes.Bge.Value==ops.Value ||
          OpCodes.Bge_S.Value==ops.Value)
          return ILFactory.Bge(true,null);
        if (OpCodes.Bge_Un.Value==ops.Value ||
          OpCodes.Bge_Un_S.Value==ops.Value)
          return ILFactory.Bge(false,null);
        if (OpCodes.Bgt.Value==ops.Value ||
          OpCodes.Bgt_S.Value==ops.Value ||
          OpCodes.Bgt_Un.Value==ops.Value ||
          OpCodes.Bgt_Un_S.Value==ops.Value)
          return ILFactory.Bgt(false,null);
        if (OpCodes.Ble.Value==ops.Value ||
          OpCodes.Ble_S.Value==ops.Value)
          return ILFactory.Ble(true,null);
        if (OpCodes.Ble_Un.Value==ops.Value ||
          OpCodes.Ble_Un_S.Value==ops.Value)
          return ILFactory.Ble(false,null);
        if (OpCodes.Blt.Value==ops.Value ||
          OpCodes.Blt_S.Value==ops.Value)
          return ILFactory.Blt(true,null);
        if (OpCodes.Blt_Un.Value==ops.Value ||
          OpCodes.Blt_Un_S.Value==ops.Value)
          return ILFactory.Blt(false,null);
        if (OpCodes.Bne_Un.Value==ops.Value ||
          OpCodes.Bne_Un_S.Value==ops.Value)
          return ILFactory.Bne_Un(null);
        if (OpCodes.Box.Value==ops.Value)
          return ILFactory.Box(null);
        if (OpCodes.Br.Value==ops.Value ||
          OpCodes.Br_S.Value==ops.Value)
          return ILFactory.Br(null);
        if (OpCodes.Break.Value==ops.Value)
          return ILFactory.Break(null);
        if (OpCodes.Brfalse.Value==ops.Value ||
          OpCodes.Brfalse_S.Value==ops.Value)
          return ILFactory.Br(false,null);
        if (OpCodes.Brtrue.Value==ops.Value ||
          OpCodes.Brtrue_S.Value==ops.Value)
          return ILFactory.Br(true,null);
        if (OpCodes.Call.Value==ops.Value ||
          OpCodes.Calli.Value==ops.Value)
          return ILFactory.Call(false,null);
        if (OpCodes.Callvirt.Value==ops.Value)
          return ILFactory.Call(true,null);
        if (OpCodes.Castclass.Value==ops.Value)
          return ILFactory.Castclass(null);
        if (OpCodes.Ceq.Value==ops.Value)
          return ILFactory.Ceq();
        if (OpCodes.Cgt.Value==ops.Value)
          return ILFactory.Cgt(true);
        if (OpCodes.Cgt_Un.Value==ops.Value)
          return ILFactory.Cgt(false);
        if (OpCodes.Ckfinite.Value==ops.Value)
          return ILFactory.Ckfinite();
        if (OpCodes.Clt.Value==ops.Value)
          return ILFactory.Clt(true);
        if (OpCodes.Clt_Un.Value==ops.Value)
          return ILFactory.Clt(false);
        if (OpCodes.Conv_I.Value==ops.Value)
          return ILFactory.Conv(typeof(IntPtr));
        if (OpCodes.Conv_I1.Value==ops.Value)
          return ILFactory.Conv(typeof(SByte));
        if (OpCodes.Conv_I2.Value==ops.Value)
          return ILFactory.Conv(typeof(Int16));
        if (OpCodes.Conv_I4.Value==ops.Value)
          return ILFactory.Conv(typeof(Int32));
        if (OpCodes.Conv_I8.Value==ops.Value)
          return ILFactory.Conv(typeof(Int64));
        if (OpCodes.Conv_Ovf_I.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(IntPtr));
        if (OpCodes.Conv_Ovf_I1.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(SByte));
        if (OpCodes.Conv_Ovf_I1_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(SByte));
        if (OpCodes.Conv_Ovf_I2.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(Int16));
        if (OpCodes.Conv_Ovf_I2_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(Int16));
        if (OpCodes.Conv_Ovf_I4.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(Int32));
        if (OpCodes.Conv_Ovf_I4_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(Int32));
        if (OpCodes.Conv_Ovf_I8.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(Int64));
        if (OpCodes.Conv_Ovf_I8_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(Int64));
        if (OpCodes.Conv_Ovf_I_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(IntPtr));
        if (OpCodes.Conv_Ovf_U.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(UIntPtr));
        if (OpCodes.Conv_Ovf_U1.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(Byte));
        if (OpCodes.Conv_Ovf_U1_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(Byte));
        if (OpCodes.Conv_Ovf_U2.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(UInt16));
        if (OpCodes.Conv_Ovf_U2_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(UInt16));
        if (OpCodes.Conv_Ovf_U4.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(UInt32));
        if (OpCodes.Conv_Ovf_U4_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(UInt32));
        if (OpCodes.Conv_Ovf_U8.Value==ops.Value)
          return ILFactory.Conv_Ovf(true,typeof(UInt64));
        if (OpCodes.Conv_Ovf_U8_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(UInt64));
        if (OpCodes.Conv_Ovf_U_Un.Value==ops.Value)
          return ILFactory.Conv_Ovf(false,typeof(UIntPtr));
        if (OpCodes.Conv_R4.Value==ops.Value)
          return ILFactory.Conv(typeof(Single));
        if (OpCodes.Conv_R8.Value==ops.Value)
          return ILFactory.Conv(typeof(Double));
        if (OpCodes.Conv_R_Un.Value==ops.Value)
          throw new InvalidOperationException("Wrong type");
        if (OpCodes.Conv_U.Value==ops.Value)
          return ILFactory.Conv(typeof(UIntPtr));
        if (OpCodes.Conv_U1.Value==ops.Value)
          return ILFactory.Conv(typeof(Byte));
        if (OpCodes.Conv_U2.Value==ops.Value)
          return ILFactory.Conv(typeof(UInt16));
        if (OpCodes.Conv_U4.Value==ops.Value)
          return ILFactory.Conv(typeof(UInt32));
        if (OpCodes.Conv_U8.Value==ops.Value)
          return ILFactory.Conv(typeof(UInt64));
        if (OpCodes.Cpblk.Value==ops.Value)
          return ILFactory.Cpblk();
        if (OpCodes.Cpobj.Value==ops.Value)
          return ILFactory.Cpobj(null);
        if (OpCodes.Div.Value==ops.Value)
          return ILFactory.Div(true);
        if (OpCodes.Div_Un.Value==ops.Value)
          return ILFactory.Div(false);
        if (OpCodes.Dup.Value==ops.Value)
          return ILFactory.Dup();
        if (OpCodes.Endfilter.Value==ops.Value)
          return ILFactory.Endfilter();
        if (OpCodes.Endfinally.Value==ops.Value)
          return ILFactory.Endfinaly();
        if (OpCodes.Initblk.Value==ops.Value)
          return ILFactory.Initblk();
        if (OpCodes.Initobj.Value==ops.Value)
          return ILFactory.Initobj(null);
        if (OpCodes.Isinst.Value==ops.Value)
          return ILFactory.Isinst(null);
        if (OpCodes.Jmp.Value==ops.Value)
          return ILFactory.Jmp(null);
        if (OpCodes.Ldarg.Value==ops.Value ||
          OpCodes.Ldarg_0.Value==ops.Value ||
          OpCodes.Ldarg_1.Value==ops.Value ||
          OpCodes.Ldarg_2.Value==ops.Value ||
          OpCodes.Ldarg_3.Value==ops.Value ||
          OpCodes.Ldarg_S.Value==ops.Value)
          return ILFactory.Ldarg(null);
        if (OpCodes.Ldarga.Value==ops.Value ||
          OpCodes.Ldarga_S.Value==ops.Value)
          return ILFactory.Ldarga(null);
        if (OpCodes.Ldc_I4.Value==ops.Value)
          return new ILNone(OpCodes.Ldc_I4);
        if (OpCodes.Ldc_I4_0.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 0);
        if (OpCodes.Ldc_I4_1.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 1);
        if (OpCodes.Ldc_I4_2.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 2);
        if (OpCodes.Ldc_I4_3.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 3);
        if (OpCodes.Ldc_I4_4.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 4);
        if (OpCodes.Ldc_I4_5.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 5);
        if (OpCodes.Ldc_I4_6.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 6);
        if (OpCodes.Ldc_I4_7.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 7);
        if (OpCodes.Ldc_I4_8.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 8);
        if (OpCodes.Ldc_I4_M1.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, -1);
        if (OpCodes.Ldc_I4_S.Value==ops.Value)
          return new ILOperandI4(OpCodes.Ldc_I4, 0);
        if (OpCodes.Ldc_I8.Value==ops.Value)
          return new ILOperandI8(OpCodes.Ldc_I8, 0);
        if (OpCodes.Ldc_R4.Value==ops.Value)
          return new ILOperandR4(OpCodes.Ldc_R4, 0);
        if (OpCodes.Ldc_R8.Value==ops.Value)
          return new ILOperandR8(OpCodes.Ldc_R8, 0);
        if (OpCodes.Ldelem_I.Value==ops.Value)
          return ILFactory.Ldelem(typeof(IntPtr));
        if (OpCodes.Ldelem_I1.Value==ops.Value)
          return ILFactory.Ldelem(typeof(SByte));
        if (OpCodes.Ldelem_I2.Value==ops.Value)
          return ILFactory.Ldelem(typeof(Int16));
        if (OpCodes.Ldelem_I4.Value==ops.Value)
          return ILFactory.Ldelem(typeof(Int32));
        if (OpCodes.Ldelem_I8.Value==ops.Value)
          return ILFactory.Ldelem(typeof(Int64));
        if (OpCodes.Ldelem_R4.Value==ops.Value)
          return ILFactory.Ldelem(typeof(Single));
        if (OpCodes.Ldelem_R8.Value==ops.Value)
          return ILFactory.Ldelem(typeof(Double));
        if (OpCodes.Ldelem_Ref.Value==ops.Value)
          return ILFactory.Ldelem(typeof(System.Object));
        if (OpCodes.Ldelem_U1.Value==ops.Value)
          return ILFactory.Ldelem(typeof(Byte));
        if (OpCodes.Ldelem_U2.Value==ops.Value)
          return ILFactory.Ldelem(typeof(UInt16));
        if (OpCodes.Ldelem_U4.Value==ops.Value)
          return ILFactory.Ldelem(typeof(UInt32));
        if (OpCodes.Ldelema.Value==ops.Value)
          return ILFactory.Ldelema(null);
        if (OpCodes.Ldfld.Value==ops.Value)
          return ILFactory.Ldfld(null);
        if (OpCodes.Ldflda.Value==ops.Value)
          return ILFactory.Ldflda(null);
        if (OpCodes.Ldftn.Value==ops.Value)
          return ILFactory.Ldftn(null);
        if (OpCodes.Ldind_I.Value==ops.Value)
          return ILFactory.Ldind(typeof(IntPtr));
        if (OpCodes.Ldind_I1.Value==ops.Value)
          return ILFactory.Ldind(typeof(SByte));
        if (OpCodes.Ldind_I2.Value==ops.Value)
          return ILFactory.Ldind(typeof(Int16));
        if (OpCodes.Ldind_I4.Value==ops.Value)
          return ILFactory.Ldind(typeof(Int32));
        if (OpCodes.Ldind_I8.Value==ops.Value)
          return ILFactory.Ldind(typeof(Int64));
        if (OpCodes.Ldind_R4.Value==ops.Value)
          return ILFactory.Ldind(typeof(Single));
        if (OpCodes.Ldind_R8.Value==ops.Value)
          return ILFactory.Ldind(typeof(Double));
        if (OpCodes.Ldind_Ref.Value==ops.Value)
          return ILFactory.Ldind(typeof(System.Object));
        if (OpCodes.Ldind_U1.Value==ops.Value)
          return ILFactory.Ldind(typeof(Byte));
        if (OpCodes.Ldind_U2.Value==ops.Value)
          return ILFactory.Ldind(typeof(UInt16));
        if (OpCodes.Ldind_U4.Value==ops.Value)
          return ILFactory.Ldind(typeof(UInt32));
        if (OpCodes.Ldlen.Value==ops.Value)
          return ILFactory.Ldlen();
        if (OpCodes.Ldloc.Value==ops.Value ||
          OpCodes.Ldloc_0.Value==ops.Value ||
          OpCodes.Ldloc_1.Value==ops.Value ||
          OpCodes.Ldloc_2.Value==ops.Value ||
          OpCodes.Ldloc_3.Value==ops.Value ||
          OpCodes.Ldloc_S.Value==ops.Value)
          return ILFactory.Ldloc(null);
        if (OpCodes.Ldloca.Value==ops.Value ||
          OpCodes.Ldloca_S.Value==ops.Value)
          return ILFactory.Ldloca(null);
        if (OpCodes.Ldnull.Value==ops.Value)
          return ILFactory.Ldnull();
        if (OpCodes.Ldobj.Value==ops.Value)
          return ILFactory.Ldobj(null);
        if (OpCodes.Ldsfld.Value==ops.Value)
          return ILFactory.Ldsfld(null);
        if (OpCodes.Ldsflda.Value==ops.Value)
          return ILFactory.Ldsflda(null);
        if (OpCodes.Ldstr.Value==ops.Value)
          return ILFactory.Ldstr("");
        if (OpCodes.Ldtoken.Value==ops.Value)
          return ILFactory.Ldtoken((RMethod)null);
        if (OpCodes.Ldvirtftn.Value==ops.Value)
          return ILFactory.Ldvirtftn(null);
        if (OpCodes.Leave.Value==ops.Value ||
          OpCodes.Leave_S.Value==ops.Value)
          return ILFactory.Leave(null);
        if (OpCodes.Localloc.Value==ops.Value)
          return ILFactory.Localloc();
        if (OpCodes.Mkrefany.Value==ops.Value)
          return ILFactory.Mkrefany(null);
        if (OpCodes.Mul.Value==ops.Value)
          return ILFactory.Mul();
        if (OpCodes.Mul_Ovf.Value==ops.Value)
          return ILFactory.Mul_Ovf(true);
        if (OpCodes.Mul_Ovf_Un.Value==ops.Value)
          return ILFactory.Mul_Ovf(false);
        if (OpCodes.Neg.Value==ops.Value)
          return ILFactory.Neg();
        if (OpCodes.Newarr.Value==ops.Value)
          return ILFactory.Newarr(null);
        if (OpCodes.Newobj.Value==ops.Value)
          return ILFactory.Newobj(null);
        if (OpCodes.Nop.Value==ops.Value)
          return ILFactory.Nop();
        if (OpCodes.Not.Value==ops.Value)
          return ILFactory.Not();
        if (OpCodes.Or.Value==ops.Value)
          return ILFactory.Or();
        if (OpCodes.Pop.Value==ops.Value)
          return ILFactory.Pop();
        if (OpCodes.Prefix1.Value==ops.Value || 
          OpCodes.Prefix2.Value==ops.Value ||
          OpCodes.Prefix3.Value==ops.Value ||
          OpCodes.Prefix4.Value==ops.Value ||
          OpCodes.Prefix5.Value==ops.Value ||
          OpCodes.Prefix6.Value==ops.Value ||
          OpCodes.Prefix7.Value==ops.Value ||
          OpCodes.Prefixref.Value==ops.Value)
          throw new InvalidOperationException("Impossible to emit");
        if (OpCodes.Refanytype.Value==ops.Value)
          return ILFactory.Refanytype();
        if (OpCodes.Refanyval.Value==ops.Value)
          return ILFactory.Refanyval(null);
        if (OpCodes.Rem.Value==ops.Value)
          return ILFactory.Rem(true);
        if (OpCodes.Rem_Un.Value==ops.Value)
          return ILFactory.Rem(false);
        if (OpCodes.Ret.Value==ops.Value)
          return ILFactory.Ret();
        if (OpCodes.Rethrow.Value==ops.Value)
          return ILFactory.Rethrow();
        if (OpCodes.Shl.Value==ops.Value)
          return ILFactory.Shl();
        if (OpCodes.Shr.Value==ops.Value)
          return ILFactory.Shr(true);
        if (OpCodes.Shr_Un.Value==ops.Value)
          return ILFactory.Shr(false);
        if (OpCodes.Sizeof.Value==ops.Value)
          return ILFactory.Sizeof(null);
        if (OpCodes.Starg.Value==ops.Value ||
          OpCodes.Starg_S.Value==ops.Value)
          return ILFactory.Starg(null);
        if (OpCodes.Stelem_I.Value==ops.Value)
          return ILFactory.Stelem(typeof(IntPtr));
        if (OpCodes.Stelem_I1.Value==ops.Value)
          return ILFactory.Stelem(typeof(SByte));
        if (OpCodes.Stelem_I2.Value==ops.Value)
          return ILFactory.Stelem(typeof(Int16));
        if (OpCodes.Stelem_I4.Value==ops.Value)
          return ILFactory.Stelem(typeof(Int32));
        if (OpCodes.Stelem_I8.Value==ops.Value)
          return ILFactory.Stelem(typeof(Int64));
        if (OpCodes.Stelem_R4.Value==ops.Value)
          return ILFactory.Stelem(typeof(Single));
        if (OpCodes.Stelem_R8.Value==ops.Value)
          return ILFactory.Stelem(typeof(Double));
        if (OpCodes.Stelem_Ref.Value==ops.Value)
          return ILFactory.Stelem(typeof(System.Object));
        if (OpCodes.Stfld.Value==ops.Value)
          return ILFactory.Stfld(null);
        if (OpCodes.Stind_I.Value==ops.Value)
          return ILFactory.Stind(typeof(IntPtr));
        if (OpCodes.Stind_I1.Value==ops.Value)
          return ILFactory.Stind(typeof(SByte));
        if (OpCodes.Stind_I2.Value==ops.Value)
          return ILFactory.Stind(typeof(Int16));
        if (OpCodes.Stind_I4.Value==ops.Value)
          return ILFactory.Stind(typeof(Int32));
        if (OpCodes.Stind_I8.Value==ops.Value)
          return ILFactory.Stind(typeof(Int64));
        if (OpCodes.Stind_R4.Value==ops.Value)
          return ILFactory.Stind(typeof(Single));
        if (OpCodes.Stind_R8.Value==ops.Value)
          return ILFactory.Stind(typeof(Double));
        if (OpCodes.Stind_Ref.Value==ops.Value)
          return ILFactory.Stind(typeof(System.Object));
        if (OpCodes.Stloc.Value==ops.Value ||
          OpCodes.Stloc_0.Value==ops.Value ||
          OpCodes.Stloc_1.Value==ops.Value ||
          OpCodes.Stloc_2.Value==ops.Value ||
          OpCodes.Stloc_3.Value==ops.Value ||
          OpCodes.Stloc_S.Value==ops.Value)
          return ILFactory.Stloc(null);
        if (OpCodes.Stobj.Value==ops.Value)
          return ILFactory.Stobj(null);
        if (OpCodes.Stsfld.Value==ops.Value)
          return ILFactory.Stsfld(null);
        if (OpCodes.Sub.Value==ops.Value)
          return ILFactory.Sub();
        if (OpCodes.Sub_Ovf.Value==ops.Value)
          return ILFactory.Sub_Ovf(true);
        if (OpCodes.Sub_Ovf_Un.Value==ops.Value)
          return ILFactory.Sub_Ovf(false);
        if (OpCodes.Switch.Value==ops.Value)
          return ILFactory.Switch(new Instruction[0]);
        if (OpCodes.Tailcall.Value==ops.Value)
          throw new InvalidOperationException();
        if (OpCodes.Throw.Value==ops.Value)
          return ILFactory.Throw();
        if (OpCodes.Unaligned.Value==ops.Value)
          throw new InvalidOperationException();
        if (OpCodes.Unbox.Value==ops.Value)
          return ILFactory.Unbox(null);
        if (OpCodes.Volatile.Value==ops.Value)
          throw new InvalidOperationException();
        if (OpCodes.Xor.Value==ops.Value)
          return ILFactory.Xor();
      return null;
    }
    private static readonly Hashtable typeToCLROperand;
  }


  /// <summary>
  /// 
  /// </summary>
  sealed class CLROperandType 
  {
    /// <summary>
    /// 
    /// </summary>
    public readonly Type t;
    /// <summary>
    /// 
    /// </summary>
    public readonly OpCode Conv;
    /// <summary>
    /// 
    /// </summary>
    public readonly OpCode Conv_Ovf;
    /// <summary>
    /// 
    /// </summary>
    public readonly OpCode Conv_Ovf_Un;
    /// <summary>
    /// 
    /// </summary>
    public readonly OpCode Ldind;
    /// <summary>
    /// 
    /// </summary>
    public readonly OpCode Stind;
    /// <summary>
    /// 
    /// </summary>
    public readonly OpCode Ldelem;
    /// <summary>
    /// 
    /// </summary>
    public readonly OpCode Stelem;

    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType I1 = 
      new CLROperandType(typeof(System.SByte), OpCodes.Conv_I1, OpCodes.Conv_Ovf_I1, OpCodes.Conv_Ovf_I1_Un, 
      OpCodes.Ldind_I1, OpCodes.Stind_I1, OpCodes.Ldelem_I1, OpCodes.Stelem_I1);

    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType I2 = 
      new CLROperandType(typeof(System.Int16), OpCodes.Conv_I2, OpCodes.Conv_Ovf_I2, OpCodes.Conv_Ovf_I2_Un, 
      OpCodes.Ldind_I2, OpCodes.Stind_I2, OpCodes.Ldelem_I2, OpCodes.Stelem_I2);

    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType I4 = 
      new CLROperandType(typeof(System.Int32), OpCodes.Conv_I4, OpCodes.Conv_Ovf_I4, OpCodes.Conv_Ovf_I4_Un, 
      OpCodes.Ldind_I4, OpCodes.Stind_I4, OpCodes.Ldelem_I4, OpCodes.Stelem_I4);

    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType I8 = 
      new CLROperandType(typeof(System.Int64), OpCodes.Conv_I8, OpCodes.Conv_Ovf_I8, OpCodes.Conv_Ovf_I8_Un, 
      OpCodes.Ldind_I8, OpCodes.Stind_I8, OpCodes.Ldelem_I8, OpCodes.Stelem_I8);
    // Unsigned types
    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType U1 = 
      new CLROperandType(typeof(System.Byte), OpCodes.Conv_U1, OpCodes.Conv_Ovf_U1, OpCodes.Conv_Ovf_U1_Un, 
      OpCodes.Ldind_U1, OpCodes.Stind_I1, OpCodes.Ldelem_U1, OpCodes.Stelem_I1);

    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType U2 = 
      new CLROperandType(typeof(System.UInt16), OpCodes.Conv_U2, OpCodes.Conv_Ovf_U1, OpCodes.Conv_Ovf_U2_Un, 
      OpCodes.Ldind_U2, OpCodes.Stind_I2, OpCodes.Ldelem_U2, OpCodes.Stelem_I2);

    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType U4 = 
      new CLROperandType(typeof(System.UInt32), OpCodes.Conv_U4, OpCodes.Conv_Ovf_U1, OpCodes.Conv_Ovf_U4_Un, 
      OpCodes.Ldind_U4, OpCodes.Stind_I4, OpCodes.Ldelem_U4, OpCodes.Stelem_I4);

    // ldind.u8 is an alias for ldind.i8
    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType U8 = 
      new CLROperandType(typeof(System.UInt64), OpCodes.Conv_U8, OpCodes.Conv_Ovf_U1, OpCodes.Conv_Ovf_U8_Un, 
      OpCodes.Ldind_I8, OpCodes.Stind_I8, OpCodes.Ldelem_I8, OpCodes.Stelem_I8);
    // Floating point types
    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType R4 = 
      new CLROperandType(typeof(System.Single), OpCodes.Conv_R4, OpCodes.Nop, OpCodes.Nop, 
      OpCodes.Ldind_R4, OpCodes.Stind_R4, OpCodes.Ldelem_R4, OpCodes.Stelem_R4);

    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType R8 = 
      new CLROperandType(typeof(System.Double), OpCodes.Conv_R8, OpCodes.Nop, OpCodes.Nop, 
      OpCodes.Ldind_R8, OpCodes.Stind_R8, OpCodes.Ldelem_R8, OpCodes.Stelem_R8);

    // Native type
    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType I = 
      new CLROperandType(typeof(System.IntPtr), OpCodes.Conv_I, OpCodes.Conv_Ovf_I, OpCodes.Conv_Ovf_I_Un, 
      OpCodes.Ldind_I, OpCodes.Stind_I, OpCodes.Ldelem_I, OpCodes.Stelem_I);

    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType U = 
      new CLROperandType(typeof(System.UIntPtr), OpCodes.Conv_U, OpCodes.Conv_Ovf_U, OpCodes.Conv_Ovf_U_Un, 
      OpCodes.Ldind_I, OpCodes.Nop, OpCodes.Ldelem_I, OpCodes.Stelem_I);
    
    /// <summary>
    /// 
    /// </summary>
    public readonly static CLROperandType O = 
      new CLROperandType(typeof(System.Object), OpCodes.Nop, OpCodes.Nop, OpCodes.Nop, 
      OpCodes.Ldind_Ref, OpCodes.Stind_Ref, OpCodes.Ldelem_Ref, OpCodes.Stelem_Ref);    

    /// <summary>
    /// 
    /// </summary>
    /// <remarks>
    /// Not all CLR operand types support the full set of operations. For those 
    /// that don't support some operations, use OpCodes.Nop as the opcode for it.
    /// </remarks>
    /// <param name="t"></param>
    /// <param name="conv"></param>
    /// <param name="conv_Ovf"></param>
    /// <param name="conv_Ovf_Un"></param>
    /// <param name="ldind"></param>
    /// <param name="stind"></param>
    /// <param name="ldelem"></param>
    /// <param name="stelem"></param>
    private CLROperandType(Type t, OpCode conv, OpCode conv_Ovf, OpCode conv_Ovf_Un, 
      OpCode ldind, OpCode stind, OpCode ldelem, OpCode stelem) 
    {
      this.t = t;
      this.Conv = conv;
      this.Conv_Ovf = conv_Ovf;
      this.Conv_Ovf_Un = conv_Ovf_Un;
      this.Ldind = ldind;
      this.Stind = stind;
      this.Ldelem = ldelem;
      this.Stelem = stelem;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public override int GetHashCode() 
    {
      return t.GetHashCode();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public override bool Equals(Object obj) 
    {
      CLROperandType oType = obj as CLROperandType;
      if (oType == null) 
      {
        return false;
      } 
      else 
      {
        return t.Equals(oType);
      }
    }
  }
}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.