private InstructionStub RecognizeInstruction() { InstructionStub instrStub = null; byte[] opcode; int opcodeLength = 1; do { opcode = ModuleReader.PeekBytes(opcodeLength); instrStub = OpcodeTable.GetValueOrDefault(opcode.ToImmutableArray()); if (instrStub == null) { opcodeLength++; } } while (instrStub == null && opcodeLength <= 3); if (instrStub == null) { throw new UnrecognizedInstructionException(); } Position += opcodeLength; return(instrStub); }
private Instruction NextInstruction() { InstructionStub instrStub = null; int instrOffset = Position; instrStub = RecognizeInstruction(); string typeName = $"{NamespaceName}.{instrStub.Name}{nameof(Instruction)}"; var type = Type.GetType(typeName); if (type == null) { type = typeof(GenericInstruction); } var instruction = (Instruction)Activator.CreateInstance(type); instruction.Name = instrStub.Name; instruction.Opcode = instrStub.Opcode; var operandBuilder = ImmutableArray.CreateBuilder <Operand>(); var typeInfo = instruction.GetType().GetTypeInfo(); foreach (var operandStub in instrStub.OperandStubs) { var operand = ReadOperand(operandStub); operand.Name = operandStub.Name; operandBuilder.Add(operand); if (!(instruction is GenericInstruction)) { var propertyInfo = typeInfo.GetDeclaredProperty(operandStub.Name); if (propertyInfo != null) { typeInfo.GetDeclaredProperty(operandStub.Name).SetValue(instruction, operand); } } } instruction.Offset = instrOffset; instruction.Length = Position - instrOffset; instruction.Operands = operandBuilder.ToImmutable(); return(instruction); }