예제 #1
0
        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);
        }
예제 #2
0
        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);
        }