| Code with Finding: |
class InstructionList {
/**
* Initialize instruction list from byte array.
*
* @param code byte array containing the instructions
*/
public InstructionList(byte[] code) {
ByteSequence bytes = new ByteSequence(code);
InstructionHandle[] ihs = new InstructionHandle[code.length];
int[] pos = new int[code.length]; // Can't be more than that
int count = 0; // Contains actual length
/* Pass 1: Create an object for each byte code and append them
* to the list.
*/
try {
while (bytes.available() > 0) {
// Remember byte offset and associate it with the instruction
int off = bytes.getIndex();
pos[count] = off;
/* Read one instruction from the byte stream, the byte position is set
* accordingly.
*/
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 (IOException e) {
throw new ClassGenException(e.toString(), e);
}
byte_positions = new int[count]; // Trim to proper size
System.arraycopy(pos, 0, byte_positions, 0, count);
/* 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) {
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
Select s = (Select) bi;
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
}
}
}
}
}
}
|