File: ILGeneratorTest.cs

package info (click to toggle)
mono 1.2.2.1-1
  • links: PTS
  • area: main
  • in suites: etch-m68k
  • size: 142,728 kB
  • ctags: 256,408
  • sloc: cs: 1,495,736; ansic: 249,442; sh: 18,304; xml: 12,463; makefile: 5,046; perl: 1,248; asm: 635; yacc: 285; sql: 7
file content (153 lines) | stat: -rw-r--r-- 3,833 bytes parent folder | download | duplicates (2)
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;
			}
		}
	}
}