List of usage examples for org.objectweb.asm Opcodes ASM5
int ASM5
To view the source code for org.objectweb.asm Opcodes ASM5.
Click Source Link
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; }