MethodInvokeUtils { public static int getArgumentCountRequiredForInvocation(AbstractInsnNode invokeNode) { Validate.notNull(invokeNode); if (invokeNode instanceof MethodInsnNode) { MethodInsnNode methodInsnNode = (MethodInsnNode) invokeNode; int extra; int paramCount; switch (methodInsnNode.getOpcode()) { case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKESPECIAL: case Opcodes.INVOKEINTERFACE: extra = 1; break; case Opcodes.INVOKESTATIC: extra = 0; break; default: throw new IllegalArgumentException(); } Type methodType = Type.getType(methodInsnNode.desc); paramCount = methodType.getArgumentTypes().length; return paramCount + extra; } else if (invokeNode instanceof InvokeDynamicInsnNode) { InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) invokeNode; int paramCount; Type methodType = Type.getType(invokeDynamicInsnNode.desc); paramCount = methodType.getArgumentTypes().length; return paramCount; } else { throw new IllegalArgumentException(); } } private  MethodInvokeUtils(); static int getArgumentCountRequiredForInvocation(AbstractInsnNode invokeNode); static Type getReturnTypeOfInvocation(AbstractInsnNode invokeNode);  }
@Test public void mustProperlyDetermineStackSizeForNormalMethod() { Type type = Type.getType(MethodUtils.getAccessibleMethod(Integer.class, "compareTo", Integer.class)); MethodInsnNode methodInsnNode = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/util/Integer", "compareTo", type.getDescriptor(), false); int reqStackCount = MethodInvokeUtils.getArgumentCountRequiredForInvocation(methodInsnNode); assertEquals(2, reqStackCount); }
@Test public void mustProperlyDetermineStackSizeForStaticMethod() { Type type = Type.getType(MethodUtils.getAccessibleMethod(Integer.class, "decode", String.class)); MethodInsnNode methodInsnNode = new MethodInsnNode(Opcodes.INVOKESTATIC, "java/util/Integer", "decode", type.getDescriptor(), false); int reqStackCount = MethodInvokeUtils.getArgumentCountRequiredForInvocation(methodInsnNode); assertEquals(1, reqStackCount); }