Export (0) Print
Expand All

ILGenerator.MarkLabel Method

Marks the Microsoft intermediate language (MSIL) stream's current position with the given label.

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

public virtual void MarkLabel(
	Label loc
)

Parameters

loc
Type: System.Reflection.Emit.Label

The label for which to set an index.

ExceptionCondition
ArgumentException

loc represents an invalid index into the label array.

-or-

An index for loc has already been defined.

A label cannot be defined more than once.

The code sample below demonstrates the contextual usage of MarkLabel to implement MSIL branching in a dynamic method.


using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class DynamicJumpTableDemo

{

   public static Type BuildMyType()
   {
	AppDomain myDomain = Thread.GetDomain();
	AssemblyName myAsmName = new AssemblyName();
	myAsmName.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,
                                             typeof(string), 
                                             new Type[] {typeof(int)});

	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();

   }

   public static void Main()
   {
	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[] {theValue}));  
			  
   }

}

.NET Framework

Supported in: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

.NET for Windows Phone apps

Supported in: Windows Phone 8.1, Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

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

Show:
© 2014 Microsoft