Expand
ILGenerator.Emit Method (OpCode)

Puts the specified instruction onto the stream of instructions.

Namespace: System.Reflection.Emit
Assembly: mscorlib (in mscorlib.dll)

Syntax

'Declaration

Public Overridable Sub Emit ( _
	opcode As OpCode _
)
'Usage

Dim instance As ILGenerator
Dim opcode As OpCode

instance.Emit(opcode)
public void Emit (
	OpCode opcode
)

Parameters

opcode

The Microsoft Intermediate Language (MSIL) instruction to be put onto the stream.

Remarks

If the opcode requires an argument, the caller must ensure that the argument length matches the length of the declared parameter. Otherwise, results will be unpredictable. For example, if the Emit instruction requires a 2-byte operand and the caller supplies a 4-byte operand, the runtime will emit two additional bytes to the instruction stream. These extra bytes will be Nop instructions.

The instruction values are defined in OpCodes.

Example

The code sample below demonstrates the use of Emit to generate MSIL output via an instance of ILGenerator.


Imports System
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit

 _

Class DynamicJumpTableDemo
   
   Public Shared Function BuildMyType() As Type

      Dim myDomain As AppDomain = Thread.GetDomain()
      Dim myAsmName As New AssemblyName()
      myAsmName.Name = "MyDynamicAssembly"
      
      Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
							AssemblyBuilderAccess.Run)
      Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
      
      Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
								 TypeAttributes.Public)
      Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
						MethodAttributes.Public Or MethodAttributes.Static, _
						GetType(String), New Type() {GetType(Integer)})
      
      Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
      
      Dim defaultCase As Label = myIL.DefineLabel()
      Dim endOfMethod As Label = myIL.DefineLabel()
      
      ' We are initializing our jump table. Note that the labels
      ' will be placed later using the MarkLabel method. 

      Dim jumpTable() As Label = {myIL.DefineLabel(), _
				  myIL.DefineLabel(), _
				  myIL.DefineLabel(), _
				  myIL.DefineLabel(), _
				  myIL.DefineLabel()}
      
      ' arg0, the number we passed, is pushed onto the stack.
      ' In this case, due to the design of the code sample,
      ' the value pushed onto the stack happens to match the
      ' index of the label (in IL terms, the index of the offset
      ' in the jump table). If this is not the case, such as
      ' when switching based on non-integer values, rules for the correspondence
      ' between the possible case values and each index of the offsets
      ' must be established outside of the ILGenerator.Emit calls,
      ' much as a compiler would.

      myIL.Emit(OpCodes.Ldarg_0)
      myIL.Emit(OpCodes.Switch, jumpTable)
      
      ' Branch on default case
      myIL.Emit(OpCodes.Br_S, defaultCase)
      
      ' Case arg0 = 0
      myIL.MarkLabel(jumpTable(0))
      myIL.Emit(OpCodes.Ldstr, "are no bananas")
      myIL.Emit(OpCodes.Br_S, endOfMethod)
      
      ' Case arg0 = 1
      myIL.MarkLabel(jumpTable(1))
      myIL.Emit(OpCodes.Ldstr, "is one banana")
      myIL.Emit(OpCodes.Br_S, endOfMethod)
      
      ' Case arg0 = 2
      myIL.MarkLabel(jumpTable(2))
      myIL.Emit(OpCodes.Ldstr, "are two bananas")
      myIL.Emit(OpCodes.Br_S, endOfMethod)
      
      ' Case arg0 = 3
      myIL.MarkLabel(jumpTable(3))
      myIL.Emit(OpCodes.Ldstr, "are three bananas")
      myIL.Emit(OpCodes.Br_S, endOfMethod)
      
      ' Case arg0 = 4
      myIL.MarkLabel(jumpTable(4))
      myIL.Emit(OpCodes.Ldstr, "are four bananas")
      myIL.Emit(OpCodes.Br_S, endOfMethod)
      
      ' Default case
      myIL.MarkLabel(defaultCase)
      myIL.Emit(OpCodes.Ldstr, "are many bananas")
      
      myIL.MarkLabel(endOfMethod)
      myIL.Emit(OpCodes.Ret)
      
      Return myTypeBuilder.CreateType()

   End Function 'BuildMyType
    
   
   Public Shared Sub Main()

      Dim myType As Type = BuildMyType()
      
      Console.Write("Enter an integer between 0 and 5: ")
      Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
      
      Console.WriteLine("---")
      Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
      Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
						 BindingFlags.InvokeMethod, Nothing, _
					         myInstance, New Object() {theValue}))

   End Sub 'Main

End Class 'DynamicJumpTableDemo


import System .* ;
import System.Threading .* ;
import System.Reflection .* ;
import System.Reflection.Emit .* ;

class DynamicJumpTableDemo
{
    public static Type BuildMyType()
    {
        AppDomain myDomain = System.Threading.Thread.GetDomain();
        AssemblyName myAsmName = new AssemblyName();
        myAsmName.set_Name("MyDynamicAssembly");
        AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly
            (myAsmName, AssemblyBuilderAccess.Run);
        ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule
            ("MyJumpTableDemo");
        TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
            TypeAttributes.Public);
        MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
            MethodAttributes.Public | MethodAttributes.Static,
            String.class.ToType(),new Type[] { int.class.ToType() });
        ILGenerator myIL = myMthdBuilder.GetILGenerator();
        Label defaultCase = myIL.DefineLabel();
        Label endOfMethod = myIL.DefineLabel();

        // We are initializing our jump table. Note that the labels
        // will be placed later using the MarkLabel method. 
        Label jumpTable[] = new Label[] { myIL.DefineLabel(),
            myIL.DefineLabel(), myIL.DefineLabel(), myIL.DefineLabel(),
            myIL.DefineLabel() };

        // arg0, the number we passed, is pushed onto the stack.
        // In this case, due to the design of the code sample,
        // the value pushed onto the stack happens to match the
        // index of the label (in IL terms, the index of the offset
        // in the jump table). If this is not the case, such as
        // when switching based on non-integer values, rules for the 
        // correspondence between the possible case values and each index 
        // of the offsets must be established outside of the ILGenerator.
        // Emit calls, much as a compiler would.
        myIL.Emit(OpCodes.Ldarg_0);
        myIL.Emit(OpCodes.Switch, jumpTable);

        // Branch on default case
        myIL.Emit(OpCodes.Br_S, defaultCase);

        // Case arg0 = 0
        myIL.MarkLabel(jumpTable[0]);
        myIL.Emit(OpCodes.Ldstr, "are no bananas");
        myIL.Emit(OpCodes.Br_S, endOfMethod);

        // Case arg0 = 1
        myIL.MarkLabel(jumpTable[1]);
        myIL.Emit(OpCodes.Ldstr, "is one banana");
        myIL.Emit(OpCodes.Br_S, endOfMethod);

        // Case arg0 = 2
        myIL.MarkLabel(jumpTable[2]);
        myIL.Emit(OpCodes.Ldstr, "are two bananas");
        myIL.Emit(OpCodes.Br_S, endOfMethod);

        // Case arg0 = 3
        myIL.MarkLabel(jumpTable[3]);
        myIL.Emit(OpCodes.Ldstr, "are three bananas");
        myIL.Emit(OpCodes.Br_S, endOfMethod);

        // Case arg0 = 4
        myIL.MarkLabel(jumpTable[4]);
        myIL.Emit(OpCodes.Ldstr, "are four bananas");
        myIL.Emit(OpCodes.Br_S, endOfMethod);

        // Default case
        myIL.MarkLabel(defaultCase);
        myIL.Emit(OpCodes.Ldstr, "are many bananas");
        myIL.MarkLabel(endOfMethod);
        myIL.Emit(OpCodes.Ret);
        return myTypeBuilder.CreateType();
    } //BuildMyType    
   
   public static void main(String[] args)
   {
        Type myType = BuildMyType();
        Console.Write("Enter an integer between 0 and 5: ");
        int theValue = Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("---");
        Object myInstance = Activator.CreateInstance(myType,new Object[0]);
        Console.WriteLine("Yes, there {0} today!",
            myType.InvokeMember("SwitchMe", BindingFlags.InvokeMethod,
            null, myInstance, new Object[]{(Int32)(theValue)}));
    } //main
} //DynamicJumpTableDemo

Platforms

Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see System Requirements.

Version Information

.NET Framework

Supported in: 2.0, 1.1, 1.0
Community ContentAdd
Page view tracker