1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
//
// ILGeneratorTest.cs - NUnit Test Cases for the ILGenerator class
//
// Marek Safar (marek.safar@seznam.cz)
//
// (C) Novell, Inc. http://www.novell.com
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using NUnit.Framework;
namespace MonoTests.System.Reflection.Emit {
[TestFixture]
public class ILGeneratorTest {
TypeBuilder tb;
ILGenerator il_gen;
static TypeBuilder DefineDynType ()
{
AssemblyName assemblyName = new AssemblyName ();
assemblyName.Name = "MonoTests.System.Reflection.Emit.ILGeneratorTest";
AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder module = assembly.DefineDynamicModule ("module1");
return module.DefineType ("T", TypeAttributes.Public);
}
void DefineBasicMethod ()
{
MethodBuilder mb = tb.DefineMethod("F",
MethodAttributes.Public, typeof(string), null);
il_gen = mb.GetILGenerator ();
}
[SetUp]
public void SetUp ()
{
tb = DefineDynType ();
}
[Test]
[ExpectedException (typeof (ArgumentNullException))]
public void DeclareLocal_NULL ()
{
DefineBasicMethod ();
il_gen.DeclareLocal (null);
}
[Test]
[ExpectedException (typeof (ArgumentException))]
public void DefineFilterBodyWithTypeNotNull ()
{
DefineBasicMethod ();
il_gen.BeginExceptionBlock ();
il_gen.EmitWriteLine ("in try");
il_gen.BeginExceptFilterBlock ();
il_gen.EmitWriteLine ("in filter head");
il_gen.BeginCatchBlock (typeof (Exception));
il_gen.EmitWriteLine ("in filter body");
il_gen.EndExceptionBlock ();
}
/// <summary>
/// Try to emit something like that:
///
/// .method public static bool TestFilter (bool execute_handler)
/// {
/// .locals init(bool)
/// try {
/// newobj instance void [mscorlib]System.Exception::.ctor()
/// throw
/// } filter {
/// pop
/// ldarg.0
/// endfilter
/// } {
/// ldc.i4.1
/// stloc.0
/// leave quit
/// }
/// ldc.i4.0
/// stloc.0
/// quit:
/// ldloc.0
/// ret
/// }
///
/// It should return true if the handler has been executed
/// Otherwise, the exception should not be catched
/// </summary>
void DefineTestFilterMethod ()
{
MethodBuilder mb = tb.DefineMethod("TestFilter",
MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new Type [] { typeof (bool) });
ConstructorInfo exCtor = typeof (Exception).GetConstructor (new Type [0]);
il_gen = mb.GetILGenerator ();
il_gen.DeclareLocal (typeof (bool));
Label quit = il_gen.DefineLabel ();
il_gen.BeginExceptionBlock ();
il_gen.Emit (OpCodes.Newobj, exCtor);
il_gen.Emit (OpCodes.Throw);
il_gen.BeginExceptFilterBlock ();
il_gen.Emit (OpCodes.Pop);
il_gen.Emit (OpCodes.Ldarg_0);
il_gen.BeginCatchBlock (null);
il_gen.Emit (OpCodes.Ldc_I4_1);
il_gen.Emit (OpCodes.Stloc_0);
il_gen.Emit (OpCodes.Leave, quit);
il_gen.EndExceptionBlock ();
il_gen.Emit (OpCodes.Ldc_I4_0);
il_gen.Emit (OpCodes.Stloc_0);
il_gen.MarkLabel (quit);
il_gen.Emit (OpCodes.Ldloc_0);
il_gen.Emit (OpCodes.Ret);
}
[Test]
public void TestFilterEmittingWithHandlerExecution ()
{
DefineTestFilterMethod ();
Type dynt = tb.CreateType ();
MethodInfo tf = dynt.GetMethod ("TestFilter");
Assert.IsTrue ((bool) tf.Invoke (null, new object [] { true }));
}
[Test]
[ExpectedException (typeof (Exception))]
public void TestFilterEmittingWithoutHandlerExecution ()
{
DefineTestFilterMethod ();
Type dynt = tb.CreateType ();
MethodInfo tf = dynt.GetMethod ("TestFilter");
try {
tf.Invoke (null, new object [] { false });
} catch (TargetInvocationException tie) {
throw tie.InnerException;
}
}
}
}
|