if (args.length == 0)
{
final InsnList doNew= new InsnList();
doNew.add(node1); // NEW
if (requireDup)
doNew.add(new InsnNode(DUP));
instructions.insertBefore(nm, doNew);
nm= doNew.getLast();
continue;
}
if (args.length == 1 && args[0].getSize() == 1)
{
final InsnList doNew= new InsnList();
doNew.add(node1); // NEW
if (requireDup)
{
doNew.add(new InsnNode(DUP));
doNew.add(new InsnNode(DUP2_X1));
doNew.add(new InsnNode(POP2));
updateMaxStack= updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values
}
else
doNew.add(new InsnNode(SWAP));
instructions.insertBefore(nm, doNew);
nm= doNew.getLast();
continue;
}
// TODO this one untested!
if ((args.length == 1 && args[0].getSize() == 2) || (args.length == 2 && args[0].getSize() == 1 && args[1].getSize() == 1))
{
final InsnList doNew= new InsnList();
doNew.add(node1); // NEW
if (requireDup)
{
doNew.add(new InsnNode(DUP));
doNew.add(new InsnNode(DUP2_X2));
doNew.add(new InsnNode(POP2));
updateMaxStack= updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values
}
else
{
doNew.add(new InsnNode(DUP_X2));
doNew.add(new InsnNode(POP));
updateMaxStack= updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for temp value
}
instructions.insertBefore(nm, doNew);
nm= doNew.getLast();
continue;
}
final InsnList doNew= new InsnList();
// generic code using temporary locals
// save stack
for (int j= args.length - 1; j >= 0; j--)
{
Type type= args[j];
doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset));
varOffset+= type.getSize();
}
if (varOffset > maxLocals)
{
maxLocals= varOffset;
}
doNew.add(node1); // NEW
if (requireDup)
doNew.add(new InsnNode(DUP));
// restore stack
for (int j= 0; j < args.length; j++)
{
Type type= args[j];
varOffset-= type.getSize();
doNew.add(new VarInsnNode(type.getOpcode(ILOAD), varOffset));
// clean up store to avoid memory leak?
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY)
{
updateMaxStack= updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for ACONST_NULL
doNew.add(new InsnNode(ACONST_NULL));
doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset));
}
}
instructions.insertBefore(nm, doNew);