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); }
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); }