private static MethodInfo GetCustomFunc <T1, T2, T3>(Func <T1, T2, T3> target)
        {
            var method   = target.Method;
            var body     = method.GetMethodBody();
            var locals   = body.LocalVariables.OrderBy(x => x.LocalIndex).ToList();
            var resolver = new ILInstructionResolver(method);

            switch (method.Name)
            {
            case nameof(TestMethods.Add_Ovf):
            case nameof(TestMethods.Add_Ovf_Un):
            {
                var instructions = ILInstructionReader.FromMethod(method);
                var parsed       = Enum.TryParse <ILOpCodeValues>(method.Name, out ILOpCodeValues result);
                var opCode       = OpCodeLookup.GetILOpcode((int)result);
                instructions[2] = new ILInstruction()
                {
                    OpCode = opCode
                };

                var compiled = ILEngineOpCodeTestMethodCompiler.CompileMethod(opCode, method, (gen) =>
                    {
                        locals.ForEach(x => gen.DeclareLocal(x.LocalType));
                        instructions.ForEach(x => x.Emit(gen, resolver));
                    });
                return(method);
            }

            default: throw new NotImplementedException();
            }
        }
Ejemplo n.º 2
0
        protected ILOpCodeValues[] CompileAndRun <T>(OpCode opCode, MethodInfo srcMethod, T expected, object[] parameters, Func <T, T, bool> comparer)
        {
            var methodParameters = srcMethod.GetParameters();
            var body             = srcMethod.GetMethodBody();
            var locals           = body.LocalVariables.OrderBy(x => x.LocalIndex).ToList();

            var parameterTypes = methodParameters.Select(x => x.ParameterType).ToArray();

            var instructions = ILInstructionReader.FromMethod(srcMethod);

            if (opCode != OpCodes.Arglist)
            {
                Assert.IsTrue(instructions.Any(x => x.OpCode == opCode), $"Opcode {opCode} missing from compiled method");
            }


            var result = ILInstructionReader
                         .FromMethod(srcMethod)
                         .Select(x => (ILOpCodeValues)x.OpCode.Value).ToArray();
            var resolver = new ILInstructionResolver(srcMethod);
            Action <ILGenerator> emitAction = (gen) =>
            {
                locals.ForEach(x => gen.DeclareLocal(x.LocalType));
                instructions.ForEach(x => x.Emit(gen, resolver));
            };

            MethodInfo method = null;

            try
            {
                method = ILEngineOpCodeTestMethodCompiler.CompileMethod(opCode, typeof(T), parameterTypes, emitAction);
            }
            catch (Exception ex)
            {
                Assert.Fail("Failed to compile method:", ex.Message);
                return(null);
            }
            return(RunAndTest <T>(method, expected, parameters, comparer));
        }