예제 #1
0
        private static void AssertUnifiedMethod(MethodDefinition method, bool methodThrows)
        {
            var instructions = method.Body.Instructions;

            instructions[0].OpCode.Should().Be(OpCodes.Nop);

            var lastIndex = instructions.Count - 1;

            instructions[lastIndex].OpCode.Should().Be(methodThrows ? OpCodes.Throw : OpCodes.Ret);
            if (method.ReturnType.Name == "Void")
            {
                if (methodThrows)
                {
                    instructions[lastIndex - 1].OpCode.Should().Be(OpCodes.Ldloc_S);
                    instructions[lastIndex - 9].OpCode.Should().Be(OpCodes.Ldloc_S);
                    instructions[lastIndex - 10].OpCode.Should().Be(OpCodes.Stloc_S);
                    instructions[lastIndex - 11].OpCode.Should().Be(OpCodes.Nop);
                }
                else
                {
                    instructions[lastIndex - 4].OpCode.Should().Be(OpCodes.Nop);
                    instructions[lastIndex - 5].OpCode.Should().Be(OpCodes.Nop);
                }
            }
            else
            {
                instructions[lastIndex - 1].OpCode.Should().Match(x => AllLdLocOpCodes.Contains((OpCode)x));

                instructions[lastIndex - 9].OpCode.Should().Be(OpCodes.Nop);
                instructions[lastIndex - 11].OpCode.Should().Be(OpCodes.Nop);
            }
        }
        private static void AssertUnifiedMethod(MethodDefinition method, bool methodThrows)
        {
            var allowedLeaveOpCodes = new List <OpCode>
            {
                OpCodes.Leave,
                OpCodes.Leave_S,
            };

            var allowedLoadOpCodes = new List <OpCode>
            {
                OpCodes.Ldloc_0,
                OpCodes.Ldloc_S,
            };

            var allowedStoreOpCodes = new List <OpCode>
            {
                OpCodes.Stloc_0,
                OpCodes.Stloc_S,
            };

            var instructions = method.Body.Instructions;

            instructions[0].OpCode.Should().Be(OpCodes.Nop);

            var lastIndex = instructions.Count - 1;

            instructions[lastIndex].OpCode.Should().Be(methodThrows ? OpCodes.Throw : OpCodes.Ret);
            if (method.ReturnType.Name == "Void")
            {
                if (methodThrows)
                {
                    instructions[lastIndex - 1].OpCode.Should().Match(x => allowedLoadOpCodes.Contains((OpCode)x));
                    instructions[lastIndex - 18].OpCode.Should().Match(x => allowedLoadOpCodes.Contains((OpCode)x));
                    instructions[lastIndex - 19].OpCode.Should().Match(x => allowedStoreOpCodes.Contains((OpCode)x));
                    instructions[lastIndex - 20].OpCode.Should().Be(OpCodes.Nop);
                }
                else
                {
                    instructions[lastIndex - 2].OpCode.Should().Be(OpCodes.Rethrow);
                    instructions[lastIndex - 12].OpCode.Should().Be(OpCodes.Nop);
                    instructions[lastIndex - 13].OpCode.Should().Match(x => allowedLeaveOpCodes.Contains((OpCode)x));
                }
            }
            else
            {
                instructions[lastIndex - 1].OpCode.Should().Match(x => AllLdLocOpCodes.Contains((OpCode)x));
                instructions[lastIndex - 2].OpCode.Should().Be(OpCodes.Nop);
                instructions[lastIndex - 3].OpCode.Should().Be(OpCodes.Rethrow);
                instructions[lastIndex - 13].OpCode.Should().Be(OpCodes.Nop);
                instructions[lastIndex - 14].OpCode.Should().Match(x => allowedLeaveOpCodes.Contains((OpCode)x));
            }
        }