// move the arguments onto the scratchpad
int ltmp = 0;
if ((access & Opcodes.ACC_STATIC) == 0) ltmp += saveArg(instructions, ltmp, Type.getType(Object.class));
for (Type at : Type.getArgumentTypes(desc)) ltmp += saveArg(instructions, ltmp, at);
instructions.add(new VarInsnNode(Opcodes.ASTORE, 0));
instructions.add(intNode(0));
instructions.add(new VarInsnNode(Opcodes.ISTORE, 1));
LabelNode loop = new LabelNode();
instructions.add(loop);
for (int i = firstJump.size() - 1; i >= 0; i--) {
LabelNode not_my_problem = new LabelNode();
instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
instructions.add(intNode(firstJump.get(i)));
instructions.add(new JumpInsnNode(Opcodes.IF_ICMPLT, not_my_problem));
instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, tgtype, name + "$f" + i, "(I[Ljava/lang/Object;)I"));
instructions.add(new VarInsnNode(Opcodes.ISTORE, 1));
instructions.add(new JumpInsnNode(Opcodes.GOTO, loop));
instructions.add(not_my_problem);
}
// time for return
String rty = null, unboxName = null, unboxDesc = null;
int retinst;
Type rtyty = Type.getReturnType(desc);
switch (rtyty.getSort()) {
case Type.VOID:
retinst = Opcodes.RETURN; break;
case Type.BOOLEAN:
case Type.CHAR:
case Type.INT:
case Type.SHORT:
case Type.BYTE:
retinst = Opcodes.IRETURN; rty = "java/lang/Integer"; unboxName = "intValue"; unboxDesc = "()I"; break;
case Type.LONG:
retinst = Opcodes.LRETURN; rty = "java/lang/Long"; unboxName = "longValue"; unboxDesc = "()J"; break;
case Type.FLOAT:
retinst = Opcodes.FRETURN; rty = "java/lang/Float"; unboxName = "floatValue"; unboxDesc = "()F"; break;
case Type.DOUBLE:
retinst = Opcodes.DRETURN; rty = "java/lang/Double"; unboxName = "doubleValue"; unboxDesc = "()D"; break;
default:
retinst = Opcodes.ARETURN; rty = rtyty.getInternalName(); break;
}
if (rty != null) {
instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
instructions.add(new InsnNode(Opcodes.ICONST_0));
instructions.add(new InsnNode(Opcodes.AALOAD));
instructions.add(new TypeInsnNode(Opcodes.CHECKCAST, rty));
if (unboxName != null)
instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, rty, unboxName, unboxDesc));