LabelNode mStart = null;// (LabelNode) mn.instructions.getFirst();
LabelNode mEnd = null; // (LabelNode) mn.instructions.getLast();
for (ListIterator<AbstractInsnNode> i = mn.instructions.iterator(); i
.hasNext();) {
AbstractInsnNode node = i.next();
if (node instanceof LabelNode) {
if (mStart == null) {
mStart = (LabelNode) node;
} else {
mEnd = (LabelNode) node;
}
} else {
if (mStart == null) {
throw new RuntimeException(
"Expected instructions of " + cn.name + " : " + mn.name + " " + mn.desc + " to start with a label, got "
+ node.getClass());
}
}
}
Label mStartl = mStart.getLabel();
if (mEnd == null) {
mEnd = new LabelNode(new Label());
mn.instructions.add(mEnd);
}
List<LocalVariableNode> paramsAndThis = new ArrayList<LocalVariableNode>();
for (Object o : mn.localVariables) {
LocalVariableNode lvn = (LocalVariableNode) o;
if (lvn.start.getLabel().equals(mStartl)) {
paramsAndThis.add(lvn);
}
}
int purrSecretIndex = 0;
for (LocalVariableNode lvn : paramsAndThis) {
purrSecretIndex += Type.getType(lvn.desc).getSize();
}
Set<String> lvNames = new HashSet<String>();
for (Object o : mn.localVariables) {
LocalVariableNode lvn = (LocalVariableNode) o;
if (lvn.index >= purrSecretIndex) {
lvn.index = lvn.index + 1;
}
lvNames.add(lvn.name);
}
String purrSecretUniqueName = makeUnique("_purrSecret", lvNames);
mn.localVariables.add(paramsAndThis.size(), new LocalVariableNode(
purrSecretUniqueName, OBJECT_DESC, null, mStart, mEnd,
purrSecretIndex));
mn.maxLocals += 1;
for (Iterator<?> i = mn.instructions.iterator(); i.hasNext();) {
Object current = i.next();
if (current instanceof VarInsnNode) {
VarInsnNode vin = (VarInsnNode) current;
if (vin.var >= purrSecretIndex) {
vin.var = vin.var + 1;
}
}
if (current instanceof IincInsnNode) {
IincInsnNode iin = (IincInsnNode) current;
iin.var = iin.var + 1;
log("Incremented iinc var to " + iin.var);
}
}
InsnList pre = new InsnList();
// pre.add(vStart);
if (isStatic) {
pre.add(new LdcInsnNode(cn.name));
} else {
pre.add(new VarInsnNode(ALOAD, 0)); // "this" is index 0 locvar.
}
pre.add(new MethodInsnNode(INVOKESTATIC, classDesc, BEFORE,
ONE_OBJECT_PARAM + OBJECT_DESC));
pre.add(new VarInsnNode(ASTORE, purrSecretIndex));
pre.add(fStart);
mn.instructions.insert(mStart, pre);
List<AbstractInsnNode> terminalNodes = new ArrayList<AbstractInsnNode>();
for (int i = 0; i < mn.instructions.size(); i++) {
AbstractInsnNode insn = mn.instructions.get(i);
int opcode = insn.getOpcode();
if (isReturnOpcode(opcode)) {
terminalNodes.add(insn);
}
}