PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/corlib/Test/System.Reflection.Emit/ILGeneratorTest.cs

https://github.com/cschlote/mono
C# | 430 lines | 357 code | 38 blank | 35 comment | 0 complexity | 7934e3a2935ccb1ddc226eaf26badb8c MD5 | raw file
  1. //
  2. // ILGeneratorTest.cs - NUnit Test Cases for the ILGenerator class
  3. //
  4. // Marek Safar (marek.safar@seznam.cz)
  5. //
  6. // (C) Novell, Inc. http://www.novell.com
  7. using System;
  8. using System.Reflection;
  9. using System.Reflection.Emit;
  10. using System.Runtime.InteropServices;
  11. using System.Threading;
  12. using NUnit.Framework;
  13. namespace MonoTests.System.Reflection.Emit
  14. {
  15. [TestFixture]
  16. public class ILGeneratorTest
  17. {
  18. TypeBuilder tb;
  19. ILGenerator il_gen;
  20. void DefineBasicMethod ()
  21. {
  22. MethodBuilder mb = tb.DefineMethod("F",
  23. MethodAttributes.Public, typeof(string), null);
  24. il_gen = mb.GetILGenerator ();
  25. }
  26. [SetUp]
  27. public void SetUp ()
  28. {
  29. AssemblyName assemblyName = new AssemblyName ();
  30. assemblyName.Name = "MonoTests.System.Reflection.Emit.ILGeneratorTest";
  31. AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
  32. assemblyName, AssemblyBuilderAccess.Run);
  33. ModuleBuilder module = assembly.DefineDynamicModule ("module1");
  34. tb = module.DefineType ("T", TypeAttributes.Public);
  35. }
  36. [Test]
  37. public void DeclareLocal_LocalType_Null ()
  38. {
  39. DefineBasicMethod ();
  40. try {
  41. il_gen.DeclareLocal (null);
  42. Assert.Fail ("#A1");
  43. } catch (ArgumentNullException ex) {
  44. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
  45. Assert.IsNull (ex.InnerException, "#A3");
  46. Assert.IsNotNull (ex.Message, "#A4");
  47. Assert.IsNotNull (ex.ParamName, "#A5");
  48. Assert.AreEqual ("localType", ex.ParamName, "#A");
  49. }
  50. #if NET_2_0
  51. try {
  52. il_gen.DeclareLocal (null, false);
  53. Assert.Fail ("#B1");
  54. } catch (ArgumentNullException ex) {
  55. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
  56. Assert.IsNull (ex.InnerException, "#B3");
  57. Assert.IsNotNull (ex.Message, "#B4");
  58. Assert.IsNotNull (ex.ParamName, "#B5");
  59. Assert.AreEqual ("localType", ex.ParamName, "#B6");
  60. }
  61. #endif
  62. }
  63. [Test]
  64. [ExpectedException (typeof (ArgumentException))]
  65. public void DefineFilterBodyWithTypeNotNull ()
  66. {
  67. DefineBasicMethod ();
  68. il_gen.BeginExceptionBlock ();
  69. il_gen.EmitWriteLine ("in try");
  70. il_gen.BeginExceptFilterBlock ();
  71. il_gen.EmitWriteLine ("in filter head");
  72. il_gen.BeginCatchBlock (typeof (Exception));
  73. il_gen.EmitWriteLine ("in filter body");
  74. il_gen.EndExceptionBlock ();
  75. }
  76. [Test] // bug #81431
  77. public void FilterAndCatchBlock ()
  78. {
  79. DefineBasicMethod ();
  80. ILGenerator il = il_gen;
  81. il.BeginExceptionBlock ();
  82. il.BeginExceptFilterBlock ();
  83. il.BeginCatchBlock (null);
  84. il.BeginCatchBlock (typeof (SystemException));
  85. }
  86. [Test]
  87. [ExpectedException (typeof (InvalidOperationException))]
  88. public void InvalidFilterBlock1 ()
  89. {
  90. DefineBasicMethod ();
  91. ILGenerator il = il_gen;
  92. il.BeginExceptionBlock ();
  93. il.BeginExceptFilterBlock ();
  94. il.EndExceptionBlock ();
  95. }
  96. [Test]
  97. public void ValidFilterBlock1 ()
  98. {
  99. DefineBasicMethod ();
  100. ILGenerator il = il_gen;
  101. il.BeginExceptionBlock ();
  102. il.BeginExceptFilterBlock ();
  103. il.BeginFaultBlock ();
  104. il.EndExceptionBlock ();
  105. }
  106. [Test]
  107. public void ValidFilterBlock2 ()
  108. {
  109. DefineBasicMethod ();
  110. ILGenerator il = il_gen;
  111. il.BeginExceptionBlock ();
  112. il.BeginExceptFilterBlock ();
  113. il.BeginFinallyBlock ();
  114. il.EndExceptionBlock ();
  115. }
  116. /// <summary>
  117. /// Try to emit something like that:
  118. ///
  119. /// .method public static bool TestFilter (bool execute_handler)
  120. /// {
  121. /// .locals init(bool)
  122. /// try {
  123. /// newobj instance void [mscorlib]System.Exception::.ctor()
  124. /// throw
  125. /// } filter {
  126. /// pop
  127. /// ldarg.0
  128. /// endfilter
  129. /// } {
  130. /// ldc.i4.1
  131. /// stloc.0
  132. /// leave quit
  133. /// }
  134. /// ldc.i4.0
  135. /// stloc.0
  136. /// quit:
  137. /// ldloc.0
  138. /// ret
  139. /// }
  140. ///
  141. /// It should return true if the handler has been executed
  142. /// Otherwise, the exception should not be catched
  143. /// </summary>
  144. void DefineTestFilterMethod ()
  145. {
  146. MethodBuilder mb = tb.DefineMethod("TestFilter",
  147. MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new Type [] { typeof (bool) });
  148. ConstructorInfo exCtor = typeof (Exception).GetConstructor (new Type [0]);
  149. il_gen = mb.GetILGenerator ();
  150. il_gen.DeclareLocal (typeof (bool));
  151. Label quit = il_gen.DefineLabel ();
  152. il_gen.BeginExceptionBlock ();
  153. il_gen.Emit (OpCodes.Newobj, exCtor);
  154. il_gen.Emit (OpCodes.Throw);
  155. il_gen.BeginExceptFilterBlock ();
  156. il_gen.Emit (OpCodes.Pop);
  157. il_gen.Emit (OpCodes.Ldarg_0);
  158. il_gen.BeginCatchBlock (null);
  159. il_gen.Emit (OpCodes.Ldc_I4_1);
  160. il_gen.Emit (OpCodes.Stloc_0);
  161. il_gen.Emit (OpCodes.Leave, quit);
  162. il_gen.EndExceptionBlock ();
  163. il_gen.Emit (OpCodes.Ldc_I4_0);
  164. il_gen.Emit (OpCodes.Stloc_0);
  165. il_gen.MarkLabel (quit);
  166. il_gen.Emit (OpCodes.Ldloc_0);
  167. il_gen.Emit (OpCodes.Ret);
  168. }
  169. [Test] // Emit (OpCode, ConstructorInfo)
  170. #if NET_2_0
  171. [Category ("NotDotNet")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
  172. #endif
  173. public void Emit3_Constructor_Null ()
  174. {
  175. DefineBasicMethod ();
  176. try {
  177. il_gen.Emit (OpCodes.Newobj, (ConstructorInfo) null);
  178. Assert.Fail ("#1");
  179. } catch (ArgumentNullException ex) {
  180. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  181. Assert.IsNull (ex.InnerException, "#3");
  182. Assert.IsNotNull (ex.Message, "#4");
  183. Assert.IsNotNull (ex.ParamName, "#5");
  184. }
  185. }
  186. #if NET_2_0
  187. [Test] // Emit (OpCode, ConstructorInfo)
  188. [Category ("NotWorking")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
  189. public void Emit3_Constructor_Null_MS ()
  190. {
  191. DefineBasicMethod ();
  192. try {
  193. il_gen.Emit (OpCodes.Newobj, (ConstructorInfo) null);
  194. Assert.Fail ("#1");
  195. } catch (NullReferenceException) {
  196. }
  197. }
  198. #endif
  199. [Test] // Emit (OpCode, FieldInfo)
  200. public void Emit5_Field_Null ()
  201. {
  202. DefineBasicMethod ();
  203. try {
  204. il_gen.Emit (OpCodes.Ldsfld, (FieldInfo) null);
  205. Assert.Fail ("#1");
  206. } catch (ArgumentNullException ex) {
  207. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  208. Assert.IsNull (ex.InnerException, "#3");
  209. Assert.IsNotNull (ex.Message, "#4");
  210. Assert.IsNotNull (ex.ParamName, "#5");
  211. }
  212. }
  213. [Test] // Emit (OpCode, Label [])
  214. [Category ("NotDotNet")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
  215. public void Emit10_Labels_Null ()
  216. {
  217. DefineBasicMethod ();
  218. try {
  219. il_gen.Emit (OpCodes.Switch, (Label []) null);
  220. Assert.Fail ("#1");
  221. } catch (ArgumentNullException ex) {
  222. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  223. Assert.IsNull (ex.InnerException, "#3");
  224. Assert.IsNotNull (ex.Message, "#4");
  225. Assert.IsNotNull (ex.ParamName, "#5");
  226. Assert.AreEqual ("labels", ex.ParamName, "#6");
  227. }
  228. }
  229. [Test]
  230. [Category ("NotWorking")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
  231. public void Emit10_Labels_Null_MS ()
  232. {
  233. DefineBasicMethod ();
  234. try {
  235. il_gen.Emit (OpCodes.Switch, (Label []) null);
  236. Assert.Fail ("#1");
  237. } catch (NullReferenceException) {
  238. }
  239. }
  240. [Test] // Emit (OpCode, LocalBuilder)
  241. public void Emit11_Local_Null ()
  242. {
  243. DefineBasicMethod ();
  244. try {
  245. il_gen.Emit (OpCodes.Switch, (LocalBuilder) null);
  246. Assert.Fail ("#1");
  247. } catch (ArgumentNullException ex) {
  248. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  249. Assert.IsNull (ex.InnerException, "#3");
  250. Assert.IsNotNull (ex.Message, "#4");
  251. Assert.IsNotNull (ex.ParamName, "#5");
  252. Assert.AreEqual ("local", ex.ParamName, "#6");
  253. }
  254. }
  255. [Test] // Emit (OpCode, MethodInfo)
  256. public void Emit12_Method_Null ()
  257. {
  258. DefineBasicMethod ();
  259. try {
  260. il_gen.Emit (OpCodes.Switch, (MethodInfo) null);
  261. Assert.Fail ("#1");
  262. } catch (ArgumentNullException ex) {
  263. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  264. Assert.IsNull (ex.InnerException, "#3");
  265. Assert.IsNotNull (ex.Message, "#4");
  266. Assert.IsNotNull (ex.ParamName, "#5");
  267. Assert.AreEqual ("meth", ex.ParamName, "#6");
  268. }
  269. }
  270. [Test] // Emit (OpCode, SignatureHelper)
  271. public void Emit14_Signature_Null ()
  272. {
  273. DefineBasicMethod ();
  274. try {
  275. il_gen.Emit (OpCodes.Switch, (SignatureHelper) null);
  276. Assert.Fail ("#1");
  277. } catch (ArgumentNullException ex) {
  278. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  279. Assert.IsNull (ex.InnerException, "#3");
  280. Assert.IsNotNull (ex.Message, "#4");
  281. Assert.IsNotNull (ex.ParamName, "#5");
  282. }
  283. }
  284. [Test] // Emit (OpCode, String)
  285. public void Emit16_String_Null ()
  286. {
  287. DefineBasicMethod ();
  288. try {
  289. il_gen.Emit (OpCodes.Switch, (String) null);
  290. Assert.Fail ("#1");
  291. } catch (ArgumentNullException ex) {
  292. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  293. Assert.IsNull (ex.InnerException, "#3");
  294. Assert.IsNotNull (ex.Message, "#4");
  295. }
  296. }
  297. [Test] // Emit (OpCode, Type)
  298. public void Emit16_Type_Null ()
  299. {
  300. DefineBasicMethod ();
  301. try {
  302. il_gen.Emit (OpCodes.Switch, (Type) null);
  303. Assert.Fail ("#1");
  304. } catch (ArgumentNullException ex) {
  305. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  306. Assert.IsNull (ex.InnerException, "#3");
  307. Assert.IsNotNull (ex.Message, "#4");
  308. Assert.IsNotNull (ex.ParamName, "#5");
  309. }
  310. }
  311. [Test]
  312. public void EmitCall_MethodInfo_Null ()
  313. {
  314. DefineBasicMethod ();
  315. try {
  316. il_gen.EmitCall (OpCodes.Call, (MethodInfo) null, null);
  317. Assert.Fail ("#1");
  318. } catch (ArgumentNullException ex) {
  319. Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
  320. Assert.IsNull (ex.InnerException, "#3");
  321. Assert.IsNotNull (ex.Message, "#4");
  322. Assert.IsNotNull (ex.ParamName, "#5");
  323. Assert.AreEqual ("methodInfo", ex.ParamName, "#6");
  324. }
  325. }
  326. [Test]
  327. public void TestFilterEmittingWithHandlerExecution ()
  328. {
  329. DefineTestFilterMethod ();
  330. Type dynt = tb.CreateType ();
  331. MethodInfo tf = dynt.GetMethod ("TestFilter");
  332. Assert.IsTrue ((bool) tf.Invoke (null, new object [] { true }));
  333. }
  334. #if NET_2_0
  335. delegate void FooFoo ();
  336. static void Foo ()
  337. {
  338. }
  339. [Test]
  340. public void TestEmitCalliWithNullReturnType ()
  341. {
  342. MethodBuilder mb = tb.DefineMethod ("F",
  343. MethodAttributes.Public | MethodAttributes.Static, null, new Type [] { typeof (IntPtr) });
  344. mb.SetImplementationFlags (MethodImplAttributes.NoInlining);
  345. il_gen = mb.GetILGenerator ();
  346. il_gen.Emit (OpCodes.Ldarg_0);
  347. il_gen.EmitCalli (OpCodes.Calli, CallingConvention.StdCall, null, Type.EmptyTypes);
  348. il_gen.Emit (OpCodes.Ret);
  349. Type dynt = tb.CreateType ();
  350. dynt.GetMethod ("F", BindingFlags.Public | BindingFlags.Static).Invoke (
  351. null, new object [] { Marshal.GetFunctionPointerForDelegate (new FooFoo (Foo)) });
  352. }
  353. #endif
  354. #if NET_2_0
  355. //Test for #509131
  356. [Test]
  357. public void TestEmitCallIgnoresOptionalArgsForNonVarargMethod ()
  358. {
  359. DefineBasicMethod ();
  360. try {
  361. il_gen.EmitCall (OpCodes.Call, typeof (object).GetMethod ("GetHashCode"), new Type[] { typeof (string) });
  362. } catch (InvalidOperationException ex) {
  363. Assert.Fail ("#1");
  364. }
  365. }
  366. #else
  367. [Test]
  368. public void TestEmitCallThrowsOnOptionalArgsForNonVarargMethod ()
  369. {
  370. DefineBasicMethod ();
  371. try {
  372. il_gen.EmitCall (OpCodes.Call, typeof (object).GetMethod ("GetHashCode"), new Type[] { typeof (string) });
  373. Assert.Fail ("#1");
  374. } catch (InvalidOperationException ex) {
  375. }
  376. }
  377. #endif
  378. [Test]
  379. [ExpectedException (typeof (Exception))]
  380. public void TestFilterEmittingWithoutHandlerExecution ()
  381. {
  382. DefineTestFilterMethod ();
  383. Type dynt = tb.CreateType ();
  384. MethodInfo tf = dynt.GetMethod ("TestFilter");
  385. try {
  386. tf.Invoke (null, new object [] { false });
  387. } catch (TargetInvocationException tie) {
  388. throw tie.InnerException;
  389. }
  390. }
  391. }
  392. }