/**
  * Creates a new {@link LocalVariablesSorter}.
  *
  * @param access access flags of the adapted method.
  * @param desc the method's descriptor (see {@link Type Type}).
  * @param mv the method visitor to which this adapter delegates calls.
  */
 public LocalVariablesSorter(final int access, final String desc, final MethodVisitor mv) {
   super(mv);
   Type[] args = Type.getArgumentTypes(desc);
   nextLocal = (Opcodes.ACC_STATIC & access) != 0 ? 0 : 1;
   for (int i = 0; i < args.length; i++) {
     nextLocal += args[i].getSize();
   }
   firstLocal = nextLocal;
 }
  /**
   * Creates a new {@link AnalyzerAdapter}.
   *
   * @param api the ASM API version implemented by this visitor. Must be one of {@link Opcodes#ASM4}
   *     or {@link Opcodes#ASM5}.
   * @param owner the owner's class name.
   * @param access the method's access flags (see {@link Opcodes}).
   * @param name the method's name.
   * @param desc the method's descriptor (see {@link Type Type}).
   * @param mv the method visitor to which this adapter delegates calls. May be <tt>null</tt>.
   */
  protected AnalyzerAdapter(
      final int api,
      final String owner,
      final int access,
      final String name,
      final String desc,
      final MethodVisitor mv) {
    super(api, mv);
    this.owner = owner;
    locals = new ArrayList<Object>();
    stack = new ArrayList<Object>();
    uninitializedTypes = new HashMap<Object, Object>();

    if ((access & Opcodes.ACC_STATIC) == 0) {
      if ("<init>".equals(name)) {
        locals.add(Opcodes.UNINITIALIZED_THIS);
      } else {
        locals.add(owner);
      }
    }
    Type[] types = Type.getArgumentTypes(desc);
    for (int i = 0; i < types.length; ++i) {
      Type type = types[i];
      switch (type.getSort()) {
        case Type.BOOLEAN:
        case Type.CHAR:
        case Type.BYTE:
        case Type.SHORT:
        case Type.INT:
          locals.add(Opcodes.INTEGER);
          break;
        case Type.FLOAT:
          locals.add(Opcodes.FLOAT);
          break;
        case Type.LONG:
          locals.add(Opcodes.LONG);
          locals.add(Opcodes.TOP);
          break;
        case Type.DOUBLE:
          locals.add(Opcodes.DOUBLE);
          locals.add(Opcodes.TOP);
          break;
        case Type.ARRAY:
          locals.add(types[i].getDescriptor());
          break;
          // case Type.OBJECT:
        default:
          locals.add(types[i].getInternalName());
      }
    }
    maxLocals = locals.size();
  }
 private void pop(final String desc) {
   char c = desc.charAt(0);
   if (c == '(') {
     int n = 0;
     Type[] types = Type.getArgumentTypes(desc);
     for (int i = 0; i < types.length; ++i) {
       n += types[i].getSize();
     }
     pop(n);
   } else if (c == 'J' || c == 'D') {
     pop(2);
   } else {
     pop(1);
   }
 }