[test] SRE ILGenerator test for methodref and fieldref token caching
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / ILGeneratorTest.cs
index 616d687ee817458fc18d95985f13716331e1d19f..c943d6859ca60634cc75f9e2278d10163aab871f 100644 (file)
@@ -58,7 +58,6 @@ namespace MonoTests.System.Reflection.Emit
                                Assert.AreEqual ("localType", ex.ParamName, "#A");
                        }
 
-#if NET_2_0
                        try {
                                il_gen.DeclareLocal (null, false);
                                Assert.Fail ("#B1");
@@ -69,7 +68,6 @@ namespace MonoTests.System.Reflection.Emit
                                Assert.IsNotNull (ex.ParamName, "#B5");
                                Assert.AreEqual ("localType", ex.ParamName, "#B6");
                        }
-#endif
                }
 
                [Test]
@@ -187,9 +185,7 @@ namespace MonoTests.System.Reflection.Emit
                }
 
                [Test] // Emit (OpCode, ConstructorInfo)
-#if NET_2_0
                [Category ("NotDotNet")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
-#endif
                public void Emit3_Constructor_Null ()
                {
                        DefineBasicMethod ();
@@ -204,7 +200,6 @@ namespace MonoTests.System.Reflection.Emit
                        }
                }
 
-#if NET_2_0
                [Test] // Emit (OpCode, ConstructorInfo)
                [Category ("NotWorking")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
                public void Emit3_Constructor_Null_MS ()
@@ -216,7 +211,6 @@ namespace MonoTests.System.Reflection.Emit
                        } catch (NullReferenceException) {
                        }
                }
-#endif
 
                [Test] // Emit (OpCode, FieldInfo)
                public void Emit5_Field_Null ()
@@ -364,7 +358,6 @@ namespace MonoTests.System.Reflection.Emit
                        Assert.IsTrue ((bool) tf.Invoke (null, new object [] { true }));
                }
 
-#if NET_2_0
                delegate void FooFoo ();
 
                static void Foo ()
@@ -386,9 +379,7 @@ namespace MonoTests.System.Reflection.Emit
                        dynt.GetMethod ("F", BindingFlags.Public | BindingFlags.Static).Invoke (
                                null, new object [] { Marshal.GetFunctionPointerForDelegate (new FooFoo (Foo)) });
                }
-#endif
 
-#if NET_2_0
                //Test for #509131
                [Test]
                public void TestEmitCallIgnoresOptionalArgsForNonVarargMethod ()
@@ -400,18 +391,6 @@ namespace MonoTests.System.Reflection.Emit
                                Assert.Fail ("#1");
                        }
                }
-#else
-               [Test]
-               public void TestEmitCallThrowsOnOptionalArgsForNonVarargMethod ()
-               {
-                       DefineBasicMethod ();
-                       try {
-                               il_gen.EmitCall (OpCodes.Call, typeof (object).GetMethod ("GetHashCode"), new Type[] { typeof (string) });
-                               Assert.Fail ("#1");
-                       } catch (InvalidOperationException ex) {
-                       }
-               }
-#endif
 
                [Test]
                [ExpectedException (typeof (Exception))]
@@ -501,5 +480,97 @@ namespace MonoTests.System.Reflection.Emit
                        Assert.AreEqual (0x02, il [14]); //typedef
                        Assert.AreEqual (0x01, il [19]); //typeref
                }
+
+               [Test]
+               public void MethodRefTokenSame () {
+                       // Get the same non-virtual method from a base and a derived type so
+                       // that the MemberInfo:DeclaredType differs but the tokens are the same.
+                       //
+                       // Regression test for bugzilla #59364
+
+                       DefineBasicMethod ();
+
+                       var m1 = typeof (object).GetMethod ("GetType");
+                       var m2 = typeof (string).GetMethod ("GetType");
+
+                       var value_getter = typeof (RuntimeMethodHandle).GetProperty ("Value").GetMethod;
+
+                       var il = il_gen;
+
+                       var loc = il.DeclareLocal (typeof (RuntimeMethodHandle));
+
+                       // return ((int)(RuntimeMethodHandle (m1).Value == RuntimeMethodHandle (m2).Value)).ToString ()
+                       il.Emit (OpCodes.Ldtoken, m1);
+                       il.Emit (OpCodes.Stloc, loc);
+                       il.Emit (OpCodes.Ldloca, loc);
+                       il.Emit (OpCodes.Call, value_getter);
+                       il.Emit (OpCodes.Ldtoken, m2);
+                       il.Emit (OpCodes.Stloc, loc);
+                       il.Emit (OpCodes.Ldloca, loc);
+                       il.Emit (OpCodes.Call, value_getter);
+                       il.Emit (OpCodes.Ceq);
+                       il.Emit (OpCodes.Box, typeof (Int32));
+                       il.Emit (OpCodes.Callvirt, typeof (object).GetMethod ("ToString"));
+                       il.Emit (OpCodes.Ret);
+
+                       var baked = tb.CreateType ();
+
+                       var x = Activator.CreateInstance (baked);
+                       var m = baked.GetMethod ("F");
+
+                       var s = m.Invoke (x, null);
+
+                       Assert.AreEqual ("1", s);
+                       
+               }
+
+               public class Base {
+                       public int x;
+               }
+
+               public class Derived : Base {
+               }
+
+               [Test]
+               public void FieldRefTokenSame () {
+                       DefineBasicMethod ();
+
+                       // Get the same field from a base and a derived type so hat
+                       // the MemberInfo:DeclaredType differs but the tokens are the same.
+                       //
+                       // Regression test for bugzilla #59364
+
+                       var f1 = typeof (Base).GetField ("x");
+                       var f2 = typeof (Derived).GetField ("x");
+
+                       var value_getter = typeof (RuntimeFieldHandle).GetProperty("Value").GetMethod;
+
+                       var il = il_gen;
+
+                       var loc = il.DeclareLocal (typeof (RuntimeFieldHandle));
+
+                       il.Emit (OpCodes.Ldtoken, f1);
+                       il.Emit (OpCodes.Stloc, loc);
+                       il.Emit (OpCodes.Ldloca, loc);
+                       il.Emit (OpCodes.Call, value_getter);
+                       il.Emit (OpCodes.Ldtoken, f2);
+                       il.Emit (OpCodes.Stloc, loc);
+                       il.Emit (OpCodes.Ldloca, loc);
+                       il.Emit (OpCodes.Call, value_getter);
+                       il.Emit (OpCodes.Ceq);
+                       il.Emit (OpCodes.Box, typeof (Int32));
+                       il.Emit (OpCodes.Callvirt, typeof (object).GetMethod ("ToString"));
+                       il.Emit (OpCodes.Ret);
+
+                       var baked = tb.CreateType ();
+
+                       var x = Activator.CreateInstance (baked);
+                       var m = baked.GetMethod ("F");
+
+                       var s = m.Invoke (x, null);
+
+                       Assert.AreEqual ("1", s);
+               }
+
        }
 }