private object ResolveOperand(ByteCodeInstructionCollection allInstructions, ByteCodeInstruction instruction)
        {
            switch (instruction.OpCode.OperandType)
            {
            case ByteCodeOperandType.PrimitiveType:
                return((PrimitiveType)(byte)instruction.Operand);

            case ByteCodeOperandType.ConstantIndex:
            case ByteCodeOperandType.WideConstantIndex:
                return(OperandResolver?.ResolveConstant(Convert.ToInt32(instruction.Operand)) ?? instruction.Operand);

            case ByteCodeOperandType.FieldIndex:
                return(OperandResolver?.ResolveField(Convert.ToInt32(instruction.Operand)) ?? instruction.Operand);

            case ByteCodeOperandType.MethodIndex:
                return(OperandResolver?.ResolveMethod(Convert.ToInt32(instruction.Operand)) ?? instruction.Operand);

            case ByteCodeOperandType.ClassIndex:
                return(OperandResolver?.ResolveClass(Convert.ToInt32(instruction.Operand)) ?? instruction.Operand);

            case ByteCodeOperandType.BranchOffset:
            case ByteCodeOperandType.WideBranchOffset:
                int offset = Convert.ToInt32(instruction.Operand);
                return(allInstructions.GetByOffset(instruction.Offset + offset) ?? instruction.Operand);
            }

            return(instruction.Operand);
        }
Esempio n. 2
0
        private object ResolveOperand(ByteCodeInstructionCollection allInstructions, ByteCodeInstruction instruction)
        {
            switch (instruction.OpCode.OperandType)
            {
            case ByteCodeOperandType.PrimitiveType:
                return((PrimitiveType)(byte)instruction.Operand);

            case ByteCodeOperandType.ConstantIndex:
            case ByteCodeOperandType.WideConstantIndex:
                return(OperandResolver?.ResolveConstant(Convert.ToInt32(instruction.Operand)) ?? instruction.Operand);

            case ByteCodeOperandType.FieldIndex:
                return(OperandResolver?.ResolveField(Convert.ToInt32(instruction.Operand)) ?? instruction.Operand);

            case ByteCodeOperandType.MethodIndex:
                return(OperandResolver?.ResolveMethod(Convert.ToInt32(instruction.Operand)) ?? instruction.Operand);

            case ByteCodeOperandType.ClassIndex:
                return(OperandResolver?.ResolveClass(Convert.ToInt32(instruction.Operand)) ?? instruction.Operand);

            case ByteCodeOperandType.DynamicIndex:
                return(OperandResolver?.ResolveDynamic(Convert.ToInt32(instruction.Operand) >> 16) ?? instruction.Operand);

            case ByteCodeOperandType.BranchOffset:
            case ByteCodeOperandType.WideBranchOffset:
                int offset = Convert.ToInt32(instruction.Operand);
                return(allInstructions.GetByOffset(instruction.Offset + offset) ?? instruction.Operand);

            case ByteCodeOperandType.TableSwitch:
                var table = (TableSwitch)instruction.Operand;
                table.DefaultOffset += instruction.Offset;
                for (int i = 0; i < table.Offsets.Count; i++)
                {
                    table.Offsets[i] += instruction.Offset;
                }
                return(table);

            case ByteCodeOperandType.LookupSwitch:
                var lookup = (LookupSwitch)instruction.Operand;
                lookup.DefaultOffset += instruction.Offset;
                foreach (int key in lookup.Table.Keys)
                {
                    lookup.Table[key] += instruction.Offset;
                }
                return(lookup);
            }

            return(instruction.Operand);
        }
        /// <summary>
        /// Disassembles the entire input buffer into Java bytecode instructions, and resolves all operands wen possible.
        /// </summary>
        /// <returns>The list of disassembled instructions.</returns>
        public IList <ByteCodeInstruction> ReadInstructions()
        {
            var result = new ByteCodeInstructionCollection();

            while (_reader.Position < _reader.StartPosition + _reader.Length)
            {
                result.Add(ReadNextInstruction());
            }

            foreach (var instruction in result)
            {
                instruction.Operand = ResolveOperand(result, instruction);
            }

            return(result);
        }