Test sizeof, mkrefany & refanyvalue in dynamic methods
authorJb Evain <jbevain@microsoft.com>
Thu, 20 Nov 2014 10:50:35 +0000 (11:50 +0100)
committerJb Evain <jbevain@microsoft.com>
Thu, 20 Nov 2014 11:59:53 +0000 (12:59 +0100)
They previously resulted in TypeLoadExceptions.

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

index f65ac28ef5ed8bed9c4d2c680c158dc52b6286d5..4aecf73b87e49354ba00c42e6d6a9d769df8297f 100644 (file)
@@ -11,6 +11,7 @@
 using System;
 using System.Reflection;
 using System.Reflection.Emit;
+using System.Runtime.InteropServices;
 using System.Text;
 
 using NUnit.Framework;
@@ -452,6 +453,62 @@ namespace MonoTests.System.Reflection.Emit
                        Assert.AreEqual (dm.Name, res.Name, "#1");
 
                }
+
+               [StructLayout (LayoutKind.Explicit)]
+               struct SizeOfTarget {
+                       [FieldOffset (0)] public int X;
+                       [FieldOffset (4)] public int Y;
+               }
+
+               [Test]
+               public void SizeOf ()
+               {
+                       var method = new DynamicMethod ("", typeof (int), Type.EmptyTypes);
+                       var il = method.GetILGenerator ();
+                       il.Emit (OpCodes.Sizeof, typeof (SizeOfTarget));
+                       il.Emit (OpCodes.Ret);
+
+                       var func = (Func<int>) method.CreateDelegate (typeof (Func<int>));
+                       var point_size = func ();
+
+                       Assert.AreEqual (8, point_size);
+               }
+
+               class TypedRefTarget {
+                       public string Name;
+               }
+
+               [Test]
+               public void TypedRef ()
+               {
+                       var method = new DynamicMethod ("", typeof (TypedRefTarget), new [] {typeof (TypedRefTarget)}, true);
+                       var il = method.GetILGenerator ();
+                       var tr = il.DeclareLocal (typeof (TypedReference));
+
+                       il.Emit (OpCodes.Ldarga, 0);
+                       il.Emit (OpCodes.Mkrefany, typeof (TypedRefTarget));
+                       il.Emit (OpCodes.Stloc, tr);
+
+                       il.Emit (OpCodes.Ldloc, tr);
+                       il.Emit (OpCodes.Call, GetType ().GetMethod ("AssertTypedRef", BindingFlags.NonPublic | BindingFlags.Static));
+
+                       il.Emit (OpCodes.Ldloc, tr);
+                       il.Emit (OpCodes.Refanyval, typeof (TypedRefTarget));
+                       il.Emit (OpCodes.Ldobj, typeof (TypedRefTarget));
+                       il.Emit (OpCodes.Ret);
+
+                       var f = (Func<TypedRefTarget, TypedRefTarget>) method.CreateDelegate (typeof (Func<TypedRefTarget, TypedRefTarget>));
+
+                       var target = new TypedRefTarget { Name = "Foo" };
+                       var rt = f (target);
+
+                       Assert.AreEqual (target, rt);
+               }
+
+               private static void AssertTypedRef (TypedReference tr)
+               {
+                       Assert.AreEqual (typeof (TypedRefTarget), TypedReference.GetTargetType (tr));
+               }
        }
 }