Example #1
0
        public void IntPtrSizeTest()
        {
            IgnoreIfNotLinkAll();

            var S8methods = new MethodInfo []
            {
                GetType().GetMethod(nameof(Size8Test), BindingFlags.NonPublic | BindingFlags.Instance),
                GetType().GetMethod(nameof(Size8Test_Optimizable), BindingFlags.NonPublic | BindingFlags.Instance)
            };
            var S4methods = new MethodInfo []
            {
                GetType().GetMethod(nameof(Size4Test), BindingFlags.NonPublic | BindingFlags.Instance),
                GetType().GetMethod(nameof(Size4Test_Optimizable), BindingFlags.NonPublic | BindingFlags.Instance)
            };

            MethodInfo[] passingMethods = null;
            MethodInfo[] failingMethods = null;
            switch (IntPtr.Size)
            {
            case 4:
                Size4Test();
                Size4Test_Optimizable();
                Assert.Throws <NUnit.Framework.Internal.NUnitException> (Size8Test, "Size8Test");
                Assert.Throws <NUnit.Framework.Internal.NUnitException> (Size8Test_Optimizable, "Size8Test_Optimizable");
                passingMethods = S4methods;
                failingMethods = S8methods;
                break;

            case 8:
                Size8Test();
                Size8Test_Optimizable();
                Assert.Throws <NUnit.Framework.Internal.NUnitException> (Size4Test, "Size4Test");
                Assert.Throws <NUnit.Framework.Internal.NUnitException> (Size4Test_Optimizable, "Size4Test_Optimizable");
                passingMethods = S8methods;
                failingMethods = S4methods;
                break;

            default:
                Assert.Fail("Invalid size: {0}", IntPtr.Size);
                break;
            }

#if !DEBUG
            // Verify that the passing method is completely empty (save for nop instructions and a final ret instruction).
            // Unfortunately in debug mode csc produces IL sequences the optimizer doesn't understand (a lot of unnecessary instructions),
            // which means we can only check this in release mode. Also on device this will probably always pass,
            // since we strip assemblies (and the methods will always be empty), but running the test shouldn't hurt.
            foreach (var passingMethod in passingMethods)
            {
                IEnumerable <ILInstruction> passingInstructions = new ILReader(passingMethod);
                passingInstructions = passingInstructions.Where((v) => v.OpCode.Name != "nop");
                Assert.AreEqual(1, passingInstructions.Count(), "empty body");
            }
#else
            // Verify that the failing methods are not completely empty (even excluding nop instructions and the final ret instruction).
            // This can only be executed in debug mode, because in release mode the IL will be stripped away and the methods will be empty.
            foreach (var failingMethod in failingMethods)
            {
                IEnumerable <ILInstruction> failingInstructions = new ILReader(failingMethod);
                failingInstructions = failingInstructions.Where((v) => v.OpCode.Name != "nop");
                Assert.That(failingInstructions.Count(), Is.GreaterThan(1), "non-empty body");
            }
#endif
        }