protected int newLocalMapping(final Type type) { int local = nextLocal; nextLocal += type.getSize(); return local; } }
/** * Returns the index of the given method argument in the frame's local * variables array. * * @param arg * the index of a method argument. * @return the index of the given method argument in the frame's local * variables array. */ private int getArgIndex(final int arg) { int index = (access & Opcodes.ACC_STATIC) == 0 ? 1 : 0; for (int i = 0; i < arg; i++) { index += argumentTypes[i].getSize(); } return index; }
/** * 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 LocalVariablesSorter}. * * @param api * the ASM API version implemented by this visitor. Must be one * of {@link Opcodes#ASM4}. * @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. */ protected LocalVariablesSorter(final int api, final int access, final String desc, final MethodVisitor mv) { super(api, mv); Type[] args = Type.getArgumentTypes(desc); nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0; for (int i = 0; i < args.length; i++) { nextLocal += args[i].getSize(); } firstLocal = nextLocal; }
private int remap(final int var, final Type type) { if (var + type.getSize() <= firstLocal) { return var; } int key = 2 * var + type.getSize() - 1; int size = mapping.length; if (key >= size) { int[] newMapping = new int[Math.max(2 * size, key + 1)]; System.arraycopy(mapping, 0, newMapping, 0, size); mapping = newMapping; } int value = mapping[key]; if (value == 0) { value = newLocalMapping(type); setLocalType(value, type); mapping[key] = value + 1; } else { value--; } if (value != var) { changed = true; } return value; }
/** * Generates the instructions to load the given method arguments on the * stack. * * @param arg * the index of the first method argument to be loaded. * @param count * the number of method arguments to be loaded. */ public void loadArgs(final int arg, final int count) { int index = getArgIndex(arg); for (int i = 0; i < count; ++i) { Type t = argumentTypes[arg + i]; loadInsn(t, index); index += t.getSize(); } }
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); } }
/** * Generates the instructions to swap the top two stack values. * * @param prev * type of the top - 1 stack value. * @param type * type of the top stack value. */ public void swap(final Type prev, final Type type) { if (type.getSize() == 1) { if (prev.getSize() == 1) { swap(); // same as dupX1(), pop(); } else { dupX2(); pop(); } } else { if (prev.getSize() == 1) { dup2X1(); pop2(); } else { dup2X2(); pop2(); } } }
@Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); if (constructor) { Type[] types = Type.getArgumentTypes(desc); for (int i = 0; i < types.length; i++) { popValue(); if (types[i].getSize() == 2) { popValue(); } } Type returnType = Type.getReturnType(desc); if (returnType != Type.VOID_TYPE) { pushValue(OTHER); if (returnType.getSize() == 2) { pushValue(OTHER); } } } }
Type boxed = getBoxedType(type); newInstance(boxed); if (type.getSize() == 2) {