in src/main/java/org/apache/bcel/generic/InstructionList.java [108:170]
public InstructionList(final byte[] code) {
int count = 0; // Contains actual length
int[] pos;
InstructionHandle[] ihs;
try (ByteSequence bytes = new ByteSequence(code)) {
ihs = new InstructionHandle[code.length];
pos = new int[code.length]; // Can't be more than that
/*
* Pass 1: Create an object for each byte code and append them to the list.
*/
while (bytes.available() > 0) {
// Remember byte offset and associate it with the instruction
final int off = bytes.getIndex();
pos[count] = off;
/*
* Read one instruction from the byte stream, the byte position is set accordingly.
*/
final Instruction i = Instruction.readInstruction(bytes);
InstructionHandle ih;
if (i instanceof BranchInstruction) {
ih = append((BranchInstruction) i);
} else {
ih = append(i);
}
ih.setPosition(off);
ihs[count] = ih;
count++;
}
} catch (final IOException e) {
throw new ClassGenException(e.toString(), e);
}
bytePositions = Arrays.copyOf(pos, count); // Trim to proper size
/*
* Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles.
*/
for (int i = 0; i < count; i++) {
if (ihs[i] instanceof BranchHandle) {
final BranchInstruction bi = (BranchInstruction) ihs[i].getInstruction();
int target = bi.getPosition() + bi.getIndex(); /*
* Byte code position: relative -> absolute.
*/
// Search for target position
InstructionHandle ih = findHandle(ihs, pos, count, target);
if (ih == null) {
throw new ClassGenException("Couldn't find target for branch: " + bi);
}
bi.setTarget(ih); // Update target
// If it is a Select instruction, update all branch targets
if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
final Select s = (Select) bi;
final int[] indices = s.getIndices();
for (int j = 0; j < indices.length; j++) {
target = bi.getPosition() + indices[j];
ih = findHandle(ihs, pos, count, target);
if (ih == null) {
throw new ClassGenException("Couldn't find target for switch: " + bi);
}
s.setTarget(j, ih); // Update target
}
}
}
}
}