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(); } }
public MethodInfo Compile() { var locals = LocalTypes.ToList(); var instructions = Instructions.ToList(); var tokenResolver = new ILInstructionResolver(Module); Dictionary <int, Label> labels = null; return(DynamicCompiler.CompileMethod(Name, ReturnType, ParameterTypes, (gen) => { locals.ForEach(x => gen.DeclareLocal(x)); labels = instructions.Where(x => x.Label.HasValue).ToDictionary(x => (int)x.Label, x => gen.DefineLabel()); instructions.ToList().ForEach(x => x.Emit(gen, tokenResolver, labels)); })); }
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)); }