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(); } }
private void ReadInstructions() { Labels.Clear(); _instructions.Clear(); using (var memory = new MemoryStream(_msilBytes)) using (var reader = new BinaryReader(memory)) while (memory.Length > memory.Position) { var opcodeOffset = (int)memory.Position; var instructionValue = (short)memory.ReadByte(); if (Prefixes.Contains(instructionValue)) { instructionValue = (short)((instructionValue << 8) | memory.ReadByte()); } if (!OpCodeLookup.TryGetValue(instructionValue, out OpCode opcode)) { var msg = $"Unknown opcode {instructionValue:X}"; _log.Error(msg); Debug.Assert(false, msg); continue; } if (opcode.Size != memory.Position - opcodeOffset) { throw new Exception( $"Opcode said it was {opcode.Size} but we read {memory.Position - opcodeOffset}"); } var instruction = new MsilInstruction(opcode) { Offset = opcodeOffset }; _instructions.Add(instruction); instruction.Operand?.Read(this, reader); } }
public CompiledTest(MethodInfo method, OpCodeTestAttribute testAttribute) { this.Method = method; var parsed = Enum.TryParse(method.Name, out ILOpCodeValues ILOpCodeValue); this.OpCode = OpCodeLookup.GetILOpcode((int)ILOpCodeValue); if (ILOpCodeValue.ToString() != Method.Name) { throw new NotImplementedException($"Iinvalid Method: '{Method.Name}'. Method names must have a matching IlOpCodeValue"); } this.TestAttribute = testAttribute; }
public void GetOpCodeArgByteSizeTest() { int actual = OpCodeLookup.GetOpCodeArgByteSize(ILOpCodeValues.Nop); int expected = 0; Assert.IsTrue(actual == expected, $"Actual:{actual}\r\nExpected:{expected}\r\n"); var metas = OpCodeMetaModel.OpCodeMetas; foreach (var meta in metas) { expected = meta.OperandTypeByteSize; try { actual = OpCodeLookup.GetOpCodeArgByteSize((ILOpCodeValues)unchecked((ushort)meta.OpCodeValue)); Assert.IsTrue(actual == expected, $"Argsize lookup failed for {meta.ClrName}\r\nActual:{actual}\r\nExpected:{expected}\r\n"); } catch (NotImplementedException) { Assert.Fail($"Argsize not implemented for failed for {meta.ClrName}: Expected: {expected}"); } } }
public void GetILOpcodeDebugNegativeTest() { var actual = OpCodeLookup.GetILOpcode(300); }
public void GetILOpcodeDebugPositiveTest() { var actual = OpCodeLookup.GetILOpcodeDebug(OpCodes.Nop.Value); var expected = OpCodes.Nop; Assert.IsTrue(actual == expected, $"Actual:{actual}\r\nExpected:{expected}\r\n"); }