Example usage for org.objectweb.asm Opcodes ASM5

List of usage examples for org.objectweb.asm Opcodes ASM5

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes ASM5.

Prototype

int ASM5

To view the source code for org.objectweb.asm Opcodes ASM5.

Click Source Link

Usage

From source file:org.coldswap.asm.field.PublicStaticFieldReplacer.java

License:Open Source License

/**
 * Replaces any GETSTATIC/PUTSTATIC call of the field in the old class with the field
 * introduced in the new class.//from  ww w.  j  ava  2s  .c om
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 */
private void replaceReferences(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    String contClass = classNode.name.substring(classNode.name.lastIndexOf("/") + 1);
    final String className = classPackage
            + TransformerNameGenerator.getPublicStaticFieldClassName(contClass, fieldNode.name);
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            }
        }
    }
}

From source file:org.coldswap.asm.method.MethodCleaner.java

License:Open Source License

@Override
public byte[] replace() {
    final ClassNode cn = new ClassNode(Opcodes.ASM5);
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    cr.accept(cn, 0);//from  w w w.java2s .c  om
    // get a list of public/protected/package/private methods but exclude
    // inherited methods.
    Method[] methods = aClass.getDeclaredMethods();
    List asmMethods = cn.methods;
    Iterator iterator = asmMethods.iterator();
    while (iterator.hasNext()) {
        final MethodNode mNode = (MethodNode) iterator.next();
        // exclude <init>() and <clinit>()
        if (!"<clinit>".equals(mNode.name) && !"<init>".equals(mNode.name)) {
            boolean foundIt = false;
            int publicAccessor = Opcodes.ACC_PUBLIC;
            // search only for public methods
            if ((mNode.access == publicAccessor)) {
                // check if this method exist in the old loaded class
                // and if not proceed with the trick.
                Type mRetType = MethodUtil.getReturnType(mNode);
                Type[] mParamType = MethodUtil.getParamsType(mNode);
                for (Method method : methods) {
                    if (mNode.name.equals(method.getName())) {
                        Type fRetType = Type.getType(method).getReturnType();
                        if (mRetType.equals(fRetType)) {
                            Type[] fParamType = MethodUtil.classToType(method.getParameterTypes());
                            boolean tmp = true;
                            if (mParamType.length == fParamType.length) {
                                for (int i = 0; i < mParamType.length; i++) {
                                    if (!mParamType[i].equals(fParamType[i])) {
                                        tmp = false;
                                    }
                                }
                            }
                            foundIt = tmp;
                        }
                    }
                }
                if (!foundIt) {
                    // remove
                    counter++;
                    iterator.remove();
                }
            }
        }
    }
    // note user about removed methods.
    if (counter > 0) {
        logger.severe(
                counter + " new methods found and removed. Please consider stopping the application because"
                        + " there might be calls to this methods that would break application state.");
    }
    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.coldswap.asm.method.PublicFloatMethodReplacer.java

License:Open Source License

@Override
public byte[] replace() {
    int counter = -1;
    final ClassNode cn = new ClassNode(Opcodes.ASM5);
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    cr.accept(cn, 0);// w ww.  j  a  v a 2 s.  co m
    List<MethodBox> factory = new ArrayList<MethodBox>();
    // find first the helper method
    MethodNode[] helperMethod = new MethodNode[maxNumberOfMethods];
    for (int i = 0; i < maxNumberOfMethods; i++) {
        helperMethod[i] = MethodUtil.createFloatHelperMethod(cn.name, i);
        cn.methods.add(helperMethod[i]);
    }
    // get a list of public/protected/package/private methods but exclude
    // inherited methods.
    Method[] methods = aClass.getDeclaredMethods();
    List asmMethods = cn.methods;
    Iterator iterator = asmMethods.iterator();
    while (iterator.hasNext()) {
        final MethodNode mNode = (MethodNode) iterator.next();
        // exclude <init>() and <clinit>()
        if (!"<clinit>".equals(mNode.name) && !"<init>".equals(mNode.name)) {
            boolean foundIt = false;
            int publicAccessor = Opcodes.ACC_PUBLIC;
            // search only for public methods
            if ((mNode.access == publicAccessor)) {
                // check if this method exist in the old loaded class
                // and if not proceed with the trick.
                Type mRetType = MethodUtil.getReturnType(mNode);
                Type[] mParamType = MethodUtil.getParamsType(mNode);
                for (Method method : methods) {
                    if (mNode.name.equals(method.getName())) {
                        Type fRetType = Type.getType(method).getReturnType();
                        if (mRetType.equals(fRetType)) {
                            Type[] fParamType = MethodUtil.classToType(method.getParameterTypes());
                            boolean tmp = true;
                            if (mParamType.length == fParamType.length) {
                                for (int i = 0; i < mParamType.length; i++) {
                                    if (!mParamType[i].equals(fParamType[i])) {
                                        tmp = false;
                                    }
                                }
                            }
                            foundIt = tmp;
                        }
                    }
                }
                if (!foundIt) {
                    // ignore any method that has return type of void
                    if (!mRetType.equals(Type.VOID_TYPE)) {
                        // work only with methods that have as a parameter int.
                        if (mParamType.length == 1 && mParamType[0].equals(Type.getType("F"))) {
                            if (counter < maxNumberOfMethods) {
                                counter++;
                                refManager.registerFieldReferenceReplacer(new PublicMethodReferenceReplacer(
                                        cn.name, mNode.name, mRetType, mParamType, Constants.FLOAT, counter));
                                // autobox return type.
                                if (AutoBoxing.isPrimitive(mRetType.getDescriptor())) {
                                    // replace any return reference with a boxing call and a areturn call
                                    mNode.instructions = replaceReturn(mNode.instructions, mRetType);
                                }
                                helperMethod[counter] = ByteCodeGenerator
                                        .insertNewNotVoidMethod(helperMethod[counter], mNode);
                                // replace method call
                                factory.add(new VirtualMethodReplacer(cn.name, mNode.name, mRetType, mParamType,
                                        Constants.FLOAT, counter));
                            }
                            // remove method
                            iterator.remove();
                        }
                    }
                }
            }
        }
    }

    // start replacing references
    for (Object asmMethod : asmMethods) {
        MethodNode container = (MethodNode) asmMethod;
        for (MethodBox methodReplacer : factory) {
            methodReplacer.replaceInvoke(container);
        }

    }

    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.coldswap.asm.method.PublicFloatMethodReplacer.java

License:Open Source License

private InsnList replaceReturn(InsnList insnList, Type retType) {
    final Type rretType = retType;
    int retOpcode = MethodUtil.getRetOpcodeToReplace(retType);
    for (int i = 0; i < insnList.size(); i++) {
        AbstractInsnNode absIns = insnList.get(i);
        int opcode = absIns.getOpcode();
        if (opcode == retOpcode) {
            // if tries to return a Reference type into a primitive then
            // remove the unbox( we return an Object). If a primitive is returned
            // into a  primitive then we must try to box from primitive to Object/Integer, etc..

            // check if an unbox takes place before return
            final boolean[] isBoxUnbox = { false, false };
            AbstractInsnNode valueOf = null;
            AbstractInsnNode primitiveValue = null;
            if (i > 1) {
                valueOf = insnList.get(i - 1);
                primitiveValue = insnList.get(i - 2);
                if (valueOf.getOpcode() == Opcodes.INVOKESTATIC) {
                    valueOf.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitMethodInsn(int i, String s, String s2, String s3) {
                            if (AutoBoxing.isPrimitive(rretType.getDescriptor())) {
                                if ((AutoBoxing.getBoxClassName(rretType) + ".valueOf").equals(s + s2)) {
                                    isBoxUnbox[0] = true;
                                }//from  w ww . j a va  2 s.  co m
                            }
                            super.visitMethodInsn(i, s, s2, s3);
                        }
                    });
                }

                if (isBoxUnbox[0] && primitiveValue.getOpcode() == Opcodes.INVOKEVIRTUAL) {
                    primitiveValue.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitMethodInsn(int i, String s, String s2, String s3) {
                            if ((s + s2).equals(AutoBoxing.getUnBoxInvoke(rretType))) {
                                isBoxUnbox[1] = true;
                            }
                            super.visitMethodInsn(i, s, s2, s3);
                        }
                    });
                }
            }

            if (isBoxUnbox[0] && isBoxUnbox[1]) {
                // remove indexes
                insnList.remove(valueOf);
                insnList.remove(primitiveValue);
            } else {
                InsnList iList = new InsnList();
                iList.add(AutoBoxing.box(retType));
                iList.add(new InsnNode(Opcodes.ARETURN));
                insnList.insertBefore(absIns, iList);
                insnList.remove(absIns);

            }
        }
    }
    return insnList;
}

From source file:org.coldswap.asm.method.PublicIntMethodReplacer.java

License:Open Source License

@Override
public byte[] replace() {
    int counter = -1;
    final ClassNode cn = new ClassNode(Opcodes.ASM5);
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    cr.accept(cn, 0);//from   ww  w .j  a v  a  2 s  . c om
    List<MethodBox> factory = new ArrayList<MethodBox>();
    // find first the helper method
    MethodNode[] helperMethod = new MethodNode[maxNumberOfMethods];
    for (int i = 0; i < maxNumberOfMethods; i++) {
        helperMethod[i] = MethodUtil.createIntHelperMethod(cn.name, i);
        cn.methods.add(helperMethod[i]);
    }
    // get a list of public/protected/package/private methods but exclude
    // inherited methods.
    Method[] methods = aClass.getDeclaredMethods();
    List asmMethods = cn.methods;
    Iterator iterator = asmMethods.iterator();
    while (iterator.hasNext()) {
        final MethodNode mNode = (MethodNode) iterator.next();
        // exclude <init>() and <clinit>()
        if (!"<clinit>".equals(mNode.name) && !"<init>".equals(mNode.name)) {
            boolean foundIt = false;
            int publicAccessor = Opcodes.ACC_PUBLIC;
            // search only for public methods
            if ((mNode.access == publicAccessor)) {
                // check if this method exist in the old loaded class
                // and if not proceed with the trick.
                Type mRetType = MethodUtil.getReturnType(mNode);
                Type[] mParamType = MethodUtil.getParamsType(mNode);
                for (Method method : methods) {
                    if (mNode.name.equals(method.getName())) {
                        Type fRetType = Type.getType(method).getReturnType();
                        if (mRetType.equals(fRetType)) {
                            Type[] fParamType = MethodUtil.classToType(method.getParameterTypes());
                            boolean tmp = true;
                            if (mParamType.length == fParamType.length) {
                                for (int i = 0; i < mParamType.length; i++) {
                                    if (!mParamType[i].equals(fParamType[i])) {
                                        tmp = false;
                                    }
                                }
                            }
                            foundIt = tmp;
                        }
                    }
                }
                if (!foundIt) {
                    // ignore any method that has return type of void
                    if (!mRetType.equals(Type.VOID_TYPE)) {
                        // work only with methods that have as a parameter int.
                        if (mParamType.length == 1 && mParamType[0].equals(Type.getType("I"))) {
                            if (counter < maxNumberOfMethods) {
                                counter++;
                                refManager.registerFieldReferenceReplacer(new PublicMethodReferenceReplacer(
                                        cn.name, mNode.name, mRetType, mParamType, Constants.INT, counter));
                                // autobox return type.
                                if (AutoBoxing.isPrimitive(mRetType.getDescriptor())) {
                                    // replace any return reference with a boxing call and a areturn call
                                    mNode.instructions = replaceReturn(mNode.instructions, mRetType);
                                }
                                helperMethod[counter] = ByteCodeGenerator
                                        .insertNewNotVoidMethod(helperMethod[counter], mNode);
                                // replace method call
                                factory.add(new VirtualMethodReplacer(cn.name, mNode.name, mRetType, mParamType,
                                        Constants.INT, counter));
                            }
                            // remove method
                            iterator.remove();
                        }
                    }
                }
            }
        }
    }

    // start replacing references
    for (Object asmMethod : asmMethods) {
        MethodNode container = (MethodNode) asmMethod;
        for (MethodBox methodReplacer : factory) {
            methodReplacer.replaceInvoke(container);
        }

    }

    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.coldswap.asm.method.PublicLongMethodReplacer.java

License:Open Source License

@Override
public byte[] replace() {
    int counter = -1;
    final ClassNode cn = new ClassNode(Opcodes.ASM5);
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    cr.accept(cn, 0);//from  w ww  . ja  va2 s  .  c  om
    List<MethodBox> factory = new ArrayList<MethodBox>();
    // find first the helper method
    MethodNode[] helperMethod = new MethodNode[maxNumberOfMethods];
    for (int i = 0; i < maxNumberOfMethods; i++) {
        helperMethod[i] = MethodUtil.createLongHelperMethod(cn.name, i);
        cn.methods.add(helperMethod[i]);
    }
    // get a list of public/protected/package/private methods but exclude
    // inherited methods.
    Method[] methods = aClass.getDeclaredMethods();
    List asmMethods = cn.methods;
    Iterator iterator = asmMethods.iterator();
    while (iterator.hasNext()) {
        final MethodNode mNode = (MethodNode) iterator.next();
        // exclude <init>() and <clinit>()
        if (!"<clinit>".equals(mNode.name) && !"<init>".equals(mNode.name)) {
            boolean foundIt = false;
            int publicAccessor = Opcodes.ACC_PUBLIC;
            // search only for public methods
            if ((mNode.access == publicAccessor)) {
                // check if this method exist in the old loaded class
                // and if not proceed with the trick.
                Type mRetType = MethodUtil.getReturnType(mNode);
                Type[] mParamType = MethodUtil.getParamsType(mNode);
                for (Method method : methods) {
                    if (mNode.name.equals(method.getName())) {
                        Type fRetType = Type.getType(method).getReturnType();
                        if (mRetType.equals(fRetType)) {
                            Type[] fParamType = MethodUtil.classToType(method.getParameterTypes());
                            boolean tmp = true;
                            if (mParamType.length == fParamType.length) {
                                for (int i = 0; i < mParamType.length; i++) {
                                    if (!mParamType[i].equals(fParamType[i])) {
                                        tmp = false;
                                    }
                                }
                            }
                            foundIt = tmp;
                        }
                    }
                }
                if (!foundIt) {
                    // ignore any method that has return type of void
                    if (!mRetType.equals(Type.VOID_TYPE)) {
                        // work only with methods that have as a parameter int.
                        if (mParamType.length == 1 && mParamType[0].equals(Type.getType("J"))) {
                            if (counter < maxNumberOfMethods) {
                                counter++;
                                refManager.registerFieldReferenceReplacer(new PublicMethodReferenceReplacer(
                                        cn.name, mNode.name, mRetType, mParamType, Constants.LONG, counter));
                                // autobox return type.
                                if (AutoBoxing.isPrimitive(mRetType.getDescriptor())) {
                                    // replace any return reference with a boxing call and a areturn call
                                    mNode.instructions = replaceReturn(mNode.instructions, mRetType);
                                }
                                helperMethod[counter] = ByteCodeGenerator
                                        .insertNewNotVoidMethod(helperMethod[counter], mNode);
                                // replace method call
                                factory.add(new VirtualMethodReplacer(cn.name, mNode.name, mRetType, mParamType,
                                        Constants.LONG, counter));
                            }
                            // remove method
                            iterator.remove();
                        }
                    }
                }
            }
        }
    }

    // start replacing references
    for (Object asmMethod : asmMethods) {
        MethodNode container = (MethodNode) asmMethod;
        for (MethodBox methodReplacer : factory) {
            methodReplacer.replaceInvoke(container);
        }

    }

    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.coldswap.asm.method.PublicObjectMethodReplacer.java

License:Open Source License

@Override
public byte[] replace() {
    int counter = -1;
    final ClassNode cn = new ClassNode(Opcodes.ASM5);
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    cr.accept(cn, 0);//from w  ww.ja  va 2 s  .com
    List<MethodBox> factory = new ArrayList<MethodBox>();
    // find first the helper method
    MethodNode[] helperMethod = new MethodNode[maxNumberOfMethods];
    for (int i = 0; i < maxNumberOfMethods; i++) {
        helperMethod[i] = MethodUtil.createObjectHelperMethod(cn.name, i);
        cn.methods.add(helperMethod[i]);
    }
    // get a list of public/protected/package/private methods but exclude
    // inherited methods.
    Method[] methods = aClass.getDeclaredMethods();
    List asmMethods = cn.methods;
    Iterator iterator = asmMethods.iterator();
    while (iterator.hasNext()) {
        final MethodNode mNode = (MethodNode) iterator.next();
        // exclude <init>() and <clinit>()
        if (!"<clinit>".equals(mNode.name) && !"<init>".equals(mNode.name)) {
            boolean foundIt = false;
            int publicAccessor = Opcodes.ACC_PUBLIC;
            // search only for public methods
            if ((mNode.access == publicAccessor)) {
                // check if this method exist in the old loaded class
                // and if not proceed with the trick.
                Type mRetType = MethodUtil.getReturnType(mNode);
                Type[] mParamType = MethodUtil.getParamsType(mNode);
                for (Method method : methods) {
                    if (mNode.name.equals(method.getName())) {
                        Type fRetType = Type.getType(method).getReturnType();
                        if (mRetType.equals(fRetType)) {
                            Type[] fParamType = MethodUtil.classToType(method.getParameterTypes());
                            boolean tmp = true;
                            if (mParamType.length == fParamType.length) {
                                for (int i = 0; i < mParamType.length; i++) {
                                    if (!mParamType[i].equals(fParamType[i])) {
                                        tmp = false;
                                    }
                                }
                            }
                            foundIt = tmp;
                        }
                    }
                }
                if (!foundIt) {
                    // ignore any method that has return type of void
                    if (!mRetType.equals(Type.VOID_TYPE)) {
                        // work only with methods that have as a parameter
                        // Object[].
                        if (mParamType.length == 1
                                && mParamType[0].equals(Type.getType("[Ljava/lang/Object;"))) {
                            if (counter < maxNumberOfMethods) {
                                counter++;
                                refManager.registerFieldReferenceReplacer(
                                        new PublicMethodReferenceReplacer(cn.name, mNode.name, mRetType,
                                                mParamType, Constants.VAROBJECT, counter));
                                // autobox return type.
                                if (AutoBoxing.isPrimitive(mRetType.getDescriptor())) {
                                    // replace any return reference with a boxing call and a areturn call
                                    mNode.instructions = replaceReturn(mNode.instructions, mRetType);
                                }
                                helperMethod[counter] = ByteCodeGenerator
                                        .insertNewNotVoidMethod(helperMethod[counter], mNode);
                                // replace method call
                                factory.add(new VirtualMethodReplacer(cn.name, mNode.name, mRetType, mParamType,
                                        Constants.VAROBJECT, counter));
                            }
                            // remove this method
                            iterator.remove();
                        }
                    }
                }
            }
        }
    }

    // start replacing references
    for (Object asmMethod : asmMethods) {
        MethodNode container = (MethodNode) asmMethod;
        for (MethodBox methodReplacer : factory) {
            methodReplacer.replaceInvoke(container);
        }

    }
    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.coldswap.asm.method.PublicObjectMethodReplacer.java

License:Open Source License

private InsnList replaceReturn(InsnList insnList, Type retType) {
    final Type rretType = retType;
    int retOpcode = MethodUtil.getRetOpcodeToReplace(retType);
    for (int i = 0; i < insnList.size(); i++) {
        AbstractInsnNode absIns = insnList.get(i);
        int opcode = absIns.getOpcode();
        if (opcode == retOpcode) {
            // if tries to return a Reference type into a primitive then
            // remove the unbox( we return an Object). If a primitive is returned
            // into a  primitive then we must try to box from primitive to Object/Integer, etc..

            // check if an unbox takes place before return
            final boolean[] isBoxUnbox = { false, false };
            AbstractInsnNode valueOf = null;
            AbstractInsnNode primitiveValue = null;
            if (i > 1) {
                valueOf = insnList.get(i - 1);
                primitiveValue = insnList.get(i - 2);
                if (valueOf.getOpcode() == Opcodes.INVOKESTATIC) {
                    valueOf.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitMethodInsn(int i, String s, String s2, String s3) {
                            if (AutoBoxing.isPrimitive(rretType.getDescriptor())) {
                                if ((AutoBoxing.getBoxClassName(rretType) + ".valueOf").equals(s + s2)) {
                                    isBoxUnbox[0] = true;
                                }/*from   w  ww  . j  a v a 2 s  . com*/
                            }
                            super.visitMethodInsn(i, s, s2, s3);
                        }
                    });
                }

                if (isBoxUnbox[0] && primitiveValue.getOpcode() == Opcodes.INVOKEVIRTUAL) {
                    primitiveValue.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitMethodInsn(int i, String s, String s2, String s3) {
                            if ((s + s2).equals(AutoBoxing.getUnBoxInvoke(rretType))) {
                                isBoxUnbox[1] = true;
                            }
                            super.visitMethodInsn(i, s, s2, s3);
                        }
                    });
                }
            }

            if (isBoxUnbox[0] && isBoxUnbox[1]) {
                // remove indexes
                insnList.remove(valueOf);
                insnList.remove(primitiveValue);
            } else {
                InsnList iList = new InsnList();
                iList.add(AutoBoxing.box(retType));
                iList.add(new InsnNode(Opcodes.ARETURN));
                insnList.insertBefore(absIns, iList);
                insnList.remove(absIns);
            }
        }
    }
    return insnList;
}

From source file:org.coldswap.asm.method.PublicStringMethodReplacer.java

License:Open Source License

@Override
public byte[] replace() {
    int counter = -1;
    final ClassNode cn = new ClassNode(Opcodes.ASM5);
    ClassReader cr = new ClassReader(bytes);
    ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    cr.accept(cn, 0);//from w  w  w  .  j av  a2s . co m
    List<MethodBox> factory = new ArrayList<MethodBox>();
    // find first the helper method
    MethodNode[] helperMethod = new MethodNode[maxNumberOfMethods];
    for (int i = 0; i < maxNumberOfMethods; i++) {
        helperMethod[i] = MethodUtil.createStringHelperMethod(cn.name, i);
        cn.methods.add(helperMethod[i]);
    }
    // get a list of public/protected/package/private methods but exclude
    // inherited methods.
    Method[] methods = aClass.getDeclaredMethods();
    List asmMethods = cn.methods;
    Iterator iterator = asmMethods.iterator();
    while (iterator.hasNext()) {
        final MethodNode mNode = (MethodNode) iterator.next();
        // exclude <init>() and <clinit>()
        if (!"<clinit>".equals(mNode.name) && !"<init>".equals(mNode.name)) {
            boolean foundIt = false;
            int publicAccessor = Opcodes.ACC_PUBLIC;
            // search only for public methods
            if ((mNode.access == publicAccessor)) {
                // check if this method exist in the old loaded class
                // and if not proceed with the trick.
                Type mRetType = MethodUtil.getReturnType(mNode);
                Type[] mParamType = MethodUtil.getParamsType(mNode);
                for (Method method : methods) {
                    if (mNode.name.equals(method.getName())) {
                        Type fRetType = Type.getType(method).getReturnType();
                        if (mRetType.equals(fRetType)) {
                            Type[] fParamType = MethodUtil.classToType(method.getParameterTypes());
                            boolean tmp = true;
                            if (mParamType.length == fParamType.length) {
                                for (int i = 0; i < mParamType.length; i++) {
                                    if (!mParamType[i].equals(fParamType[i])) {
                                        tmp = false;
                                    }
                                }
                            }
                            foundIt = tmp;
                        }
                    }
                }
                if (!foundIt) {
                    // ignore any method that has return type of void
                    if (!mRetType.equals(Type.VOID_TYPE)) {
                        // work only with methods that have as a parameter int.
                        if (mParamType.length == 1
                                && mParamType[0].equals(Type.getType("Ljava/lang/String;"))) {
                            if (counter < maxNumberOfMethods) {
                                counter++;
                                refManager.registerFieldReferenceReplacer(new PublicMethodReferenceReplacer(
                                        cn.name, mNode.name, mRetType, mParamType, Constants.STRING, counter));
                                // autobox return type.
                                if (AutoBoxing.isPrimitive(mRetType.getDescriptor())) {
                                    // replace any return reference with a boxing call and a areturn call
                                    mNode.instructions = replaceReturn(mNode.instructions, mRetType);
                                }
                                helperMethod[counter] = ByteCodeGenerator
                                        .insertNewNotVoidMethod(helperMethod[counter], mNode);
                                // replace method call
                                factory.add(new VirtualMethodReplacer(cn.name, mNode.name, mRetType, mParamType,
                                        Constants.STRING, counter));
                            }
                            // remove method
                            iterator.remove();
                        }
                    }
                }
            }
        }
    }

    // start replacing references
    for (Object asmMethod : asmMethods) {
        MethodNode container = (MethodNode) asmMethod;
        for (MethodBox methodReplacer : factory) {
            methodReplacer.replaceInvoke(container);
        }

    }

    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.coldswap.asm.VirtualMethodReplacer.java

License:Open Source License

@Override
public MethodNode replaceInvoke(MethodNode methodNode) {
    InsnList instructions = methodNode.instructions;
    Iterator it = instructions.iterator();
    while (it.hasNext()) {
        AbstractInsnNode code = (AbstractInsnNode) it.next();
        if (code.getOpcode() == Opcodes.INVOKEVIRTUAL) {
            // check if methodToReplace is called
            final boolean[] callFounded = new boolean[] { false };
            code.accept(new MethodVisitor(Opcodes.ASM5) {
                @Override/*w  ww  .j a  v a2 s  .  c o m*/
                public void visitMethodInsn(int i, String s, String s2, String s3) {
                    if (s.equals(classContainer) && s2.equals(methodName)) {
                        callFounded[0] = true;
                    }
                    super.visitMethodInsn(i, s, s2, s3);
                }
            });

            if (callFounded[0]) {
                // if the return type is primitive and the value is not discarded, unbox
                if (AutoBoxing.isPrimitive(retType.getDescriptor())) {
                    AbstractInsnNode codeNext = code.getNext();
                    boolean discarded = false;
                    // if returning primitive double or long and it is discarded with a pop2 than discard with
                    // simple pop, because we use an Object as return value.
                    if (codeNext.getOpcode() == Opcodes.POP2
                            && (retType.getDescriptor().equals("D") || retType.getDescriptor().equals("J"))) {
                        instructions.set(codeNext, new InsnNode(Opcodes.POP));

                    }
                    if (codeNext.getOpcode() == Opcodes.POP || codeNext.getOpcode() == Opcodes.POP2) {
                        discarded = true;
                    }
                    if (!discarded) {
                        instructions.insert(code, AutoBoxing.unbox(retType));
                    }
                }

                // replace call with a custom call
                String newMethodName;
                AbstractInsnNode newInvoke = null;
                if (Constants.VAROBJECT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getObjectMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "([Ljava/lang/Object;)Ljava/lang/Object;");
                } else if (Constants.INT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getIntMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(I)Ljava/lang/Object;");
                } else if (Constants.FLOAT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getFloatMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(F)Ljava/lang/Object;");
                } else if (Constants.STRING.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getStringMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(Ljava/lang/String;)Ljava/lang/Object;");
                } else if (Constants.LONG.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getLongMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(J)Ljava/lang/Object;");
                }
                if (newInvoke != null) {
                    instructions.set(code, newInvoke);
                }
            }
        }
    }
    return methodNode;
}