Example usage for org.objectweb.asm.tree InsnList remove

List of usage examples for org.objectweb.asm.tree InsnList remove

Introduction

In this page you can find the example usage for org.objectweb.asm.tree InsnList remove.

Prototype

public void remove(final AbstractInsnNode insnNode) 

Source Link

Document

Removes the given instruction from this list.

Usage

From source file:com.android.builder.testing.MockableJarGenerator.java

License:Apache License

/**
 * Rewrites the method bytecode to remove the "Stub!" exception.
 */// ww w .  ja  v  a  2  s .  c  om
private void fixMethodBody(MethodNode methodNode, ClassNode classNode) {
    if ((methodNode.access & Opcodes.ACC_NATIVE) != 0 || (methodNode.access & Opcodes.ACC_ABSTRACT) != 0) {
        // Abstract and native method don't have bodies to rewrite.
        return;
    }

    if ((classNode.access & Opcodes.ACC_ENUM) != 0 && ENUM_METHODS.contains(methodNode.name)) {
        // Don't break enum classes.
        return;
    }

    Type returnType = Type.getReturnType(methodNode.desc);
    InsnList instructions = methodNode.instructions;

    if (methodNode.name.equals(CONSTRUCTOR)) {
        // Keep the call to parent constructor, delete the exception after that.

        boolean deadCode = false;
        for (AbstractInsnNode instruction : instructions.toArray()) {
            if (!deadCode) {
                if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) {
                    instructions.insert(instruction, new InsnNode(Opcodes.RETURN));
                    // Start removing all following instructions.
                    deadCode = true;
                }
            } else {
                instructions.remove(instruction);
            }
        }
    } else {
        instructions.clear();

        if (returnDefaultValues || methodNode.name.equals(CLASS_CONSTRUCTOR)) {
            if (INTEGER_LIKE_TYPES.contains(returnType)) {
                instructions.add(new InsnNode(Opcodes.ICONST_0));
            } else if (returnType.equals(Type.LONG_TYPE)) {
                instructions.add(new InsnNode(Opcodes.LCONST_0));
            } else if (returnType.equals(Type.FLOAT_TYPE)) {
                instructions.add(new InsnNode(Opcodes.FCONST_0));
            } else if (returnType.equals(Type.DOUBLE_TYPE)) {
                instructions.add(new InsnNode(Opcodes.DCONST_0));
            } else {
                instructions.add(new InsnNode(Opcodes.ACONST_NULL));
            }

            instructions.add(new InsnNode(returnType.getOpcode(Opcodes.IRETURN)));
        } else {
            instructions.insert(throwExceptionsList(methodNode, classNode));
        }
    }
}

From source file:com.github.antag99.retinazer.weaver.SystemProcessor.java

License:Open Source License

private void processMethod(MethodNode methodNode) {
    InsnList insns = methodNode.instructions;

    // Filter out debugging nodes/labels
    int count = 0;
    int maxCount = insns.size();
    AbstractInsnNode[] nodes = new AbstractInsnNode[maxCount];
    for (AbstractInsnNode node = insns.getFirst(); node != null; node = node.getNext())
        if (node.getOpcode() > 0)
            nodes[count++] = node;/* w w w . ja va  2  s .  c o m*/

    // Find mapper get() calls and create an own flyweight instance for each
    for (int i = 0; i <= count - 4; i++) {
        if (!(nodes[i + 0] instanceof VarInsnNode))
            continue;
        if (!(nodes[i + 1] instanceof FieldInsnNode))
            continue;
        if (!(nodes[i + 2] instanceof VarInsnNode))
            continue;
        if (!(nodes[i + 3] instanceof MethodInsnNode))
            continue;

        VarInsnNode loadThis = (VarInsnNode) nodes[i + 0];
        FieldInsnNode getField = (FieldInsnNode) nodes[i + 1];
        VarInsnNode loadEntity = (VarInsnNode) nodes[i + 2];
        MethodInsnNode getMethod = (MethodInsnNode) nodes[i + 3];

        if (loadThis.var != 0 || loadThis.getOpcode() != ALOAD)
            continue;

        if (!getField.owner.equals(metadata.internalName)
                || !getField.desc.equals("L" + WeaverConstants.MAPPER_NAME + ";")
                || !metadata.mappersByName.containsKey(getField.name))
            continue;
        if (loadEntity.getOpcode() != ILOAD)
            continue;
        if (!getMethod.owner.equals(WeaverConstants.MAPPER_NAME)
                || !getMethod.desc.equals("(I)L" + WeaverConstants.COMPONENT_NAME + ";")
                || !getMethod.name.equals("get"))
            continue;

        SystemMapper mapper = metadata.mappersByName.get(getField.name);

        // Add field to hold the flyweight
        String fieldName = "flyweight$" + flyweightFields.size();
        String fieldDesc = mapper.componentType.getDescriptor();
        FieldNode fieldNode = new FieldNode(ACC_PRIVATE, fieldName, fieldDesc, null, null);
        fieldNode.visitAnnotation("Lcom/github/antag99/retinazer/SkipWire;", true);
        FlyweightField flyweightField = new FlyweightField();
        flyweightField.fieldNode = fieldNode;
        flyweightField.mapper = mapper;
        flyweightFields.add(flyweightField);

        // Rewrite access to use the flyweight
        getField.owner = metadata.internalName;
        getField.name = fieldName;
        getField.desc = fieldDesc;
        insns.insert(getField, new InsnNode(DUP));
        insns.insert(loadEntity, new FieldInsnNode(PUTFIELD, mapper.componentType.getInternalName(),
                WeaverConstants.INDEX_FIELD_NAME, WeaverConstants.INDEX_FIELD_DESC));
        insns.remove(getMethod);
    }
}

From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java

@Test
public void testInjectingIntoMethodWithLotsOfParameters() throws Exception {
    final String FIELDPROXYWORKED = "FIELDPROXYWORKED";

    //set up the proxy object. this is the object that will receive
    //the proxied calls
    TestSubClass tcc = new TestSubClass();
    tcc.setBaseString(FIELDPROXYWORKED);

    TestBaseClassHolder.setTestBase(tcc);

    //get the dynamic source that has the donor body in it
    ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF2);
    MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout");

    System.out.println("Donor Method Before Modifications:");
    printMethodNode(donorMethod);/*from   w  w  w. j a  v a 2s.  c  o m*/

    String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.Concatenator";
    ClassNode targetSource = loadLocalClass(TARGETCLASSNAME);

    ClassNode exampleSource = loadLocalClass("com.triage.bytecodemaster.fortesting.JustLikeGroovyClass");
    MethodNode exampleMethod = findMethod(exampleSource, "before_whatDoIThinkAbout");

    System.out.println("Example Method-- Should be just like the Donor Source");
    printMethodNode(exampleMethod);
    MethodNode targetMethod = findMethod(targetSource, "concat");
    System.out.println("Target Method <Before Mods>");
    printMethodNode(targetMethod);

    //alright here's the strategy:  (1) inject a new local variable that points 
    //   to our remote instance,
    //  (2) inject code that sets this local to the value of a method call,
    //  (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1

    InsnList instructionsToInject = donorMethod.instructions;
    InsnList targetInstructions = targetMethod.instructions;

    //make a new local variable in the donor method.
    //this variable needs to have a slot high enough that it doesnt
    //conflict with either the target or the source method
    //it will hold references to the objects we replace with 'this'
    LabelNode begin = new LabelNode();
    LabelNode end = new LabelNode();
    targetInstructions.insertBefore(targetInstructions.getFirst(), begin);
    targetInstructions.add(end);

    Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass");
    int variableIndex = targetMethod.maxLocals;
    targetMethod.maxLocals += type.getSize();
    targetMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(),
            variableIndex);

    //set the value of the local variable with a new instruction at the top
    //fetch a reference to our proxy object
    MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC,
            "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase",
            "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;");

    //insert after begin label
    targetInstructions.insert(begin, getTestBase);

    //store reference
    VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex);

    //insert store after fetch
    targetInstructions.insert(getTestBase, setRef);

    //replace all references to 'this' in the DONOR method with the new variable
    //in the TARGET code

    for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) {
        AbstractInsnNode node = instructionsToInject.get(currentIndex);
        if (node.getOpcode() == Opcodes.ALOAD) {
            VarInsnNode vin = (VarInsnNode) node;

            //'this' is var index 0. ours is var index varindex
            if (vin.var == 0) {
                vin.var = variableIndex;
            }
        }

        //remove return methods. this will prevent a return. it should cause the donor 
        //method to have parameters that overlap with the target, which has more parameters
        if (node.getOpcode() == Opcodes.RETURN || node.getOpcode() == Opcodes.ARETURN) {
            instructionsToInject.remove(node);
        }
    }

    System.out.println(">>>>>>>>>Finished Modifying Donor Method <<<<<<<<");
    printMethodNode(donorMethod);
    String NEWCLASSNAME = "ScriptTestClass";

    //stash instructions at the beginning of the original method, 
    //but after populating the new variable
    targetInstructions.insert(setRef, instructionsToInject);

    System.out.println("Modified Target:");
    printMethodNode(targetMethod);

    //write a class 
    Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME);

    Object o = c.newInstance();
    Method m = o.getClass().getDeclaredMethod("concat", String.class, String.class, String.class, String.class);

    //should return HAHAHA not baseStringValue 
    String result = (String) m.invoke(o, new Object[] { "A", "B", "C", "D" });
    System.out.println("Concatenator.concat Result: " + result);
    assertTrue(result.equals("ABCD"));

}

From source file:com.typesafe.path_hole.PathHole.java

License:Open Source License

private static byte[] prependToClassLoader() {
    Object[] ourEnhancementsToLoadClass = getMethodNode(PathHole.class, "bytecodeToPrepend",
            "(Ljava/lang/String;Z)V");
    Object[] jlClassLoader = getMethodNode(ClassLoader.class, "loadClass",
            "(Ljava/lang/String;Z)Ljava/lang/Class;");

    // get the bytecode to prepend
    InsnList prependInst = ((MethodNode) ourEnhancementsToLoadClass[1]).instructions;

    // lets get rid of the return statement
    // remove the optional label
    if (prependInst.getLast().getOpcode() < 0) {
        prependInst.remove(prependInst.getLast());
    }/*  ww  w.j ava 2s .c o m*/
    // remove the return inst. It doesn't take any args so this is all we need
    prependInst.remove(prependInst.getLast());

    // now add this to loadClass method of jlClassLoader
    InsnList baseInst = ((MethodNode) jlClassLoader[1]).instructions;
    baseInst.insertBefore(baseInst.getFirst(), prependInst);

    ClassNode clClassNode = (ClassNode) jlClassLoader[0];
    //        we just need to add any fields referenced by the prepended bytecode to the jlClassLoader
    //        ClassNode prependClassNode = (ClassNode) ourEnhancementsToLoadClass[0];

    // write the new bytecode
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    clClassNode.accept(cw);
    return cw.toByteArray();
}

From source file:de.tuberlin.uebb.jbop.optimizer.arithmetic.ArithmeticExpressionInterpreter.java

License:Open Source License

private void clean(final InsnList original, final Iterator<AbstractInsnNode> iterator,
        final AbstractInsnNode currentNode, final AbstractInsnNode numberNode, final AbstractInsnNode castNode1,
        final AbstractInsnNode castNode2, final AbstractInsnNode op) {
    if (castNode1 != null) {
        iterator.next();// --> castNode1
    }//from  w  ww  .ja  v a 2  s. c o  m
    iterator.next();// --> numberNode
    if (castNode2 != null) {
        iterator.next();// --> castNode2
    }
    iterator.next();// --> op
    original.remove(currentNode);
    if (castNode1 != null) {
        original.remove(castNode1);
    }
    original.remove(numberNode);
    if (castNode2 != null) {
        original.remove(castNode2);
    }
    original.remove(op);
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayLengthInliner.java

License:Open Source License

@Override
public InsnList optimize(final InsnList original, final MethodNode method) throws JBOPClassException {
    optimized = false;// w  w w  . jav  a 2s .c  o  m
    final ListIterator<AbstractInsnNode> iterator = original.iterator();
    final ArrayHelper arrayHelper = new ArrayHelper();
    while (iterator.hasNext()) {
        final AbstractInsnNode aload = iterator.next();
        if (!arrayHelper.isArrayInstruction(classNode, aload, null)) {
            continue;
        }
        if (!arrayHelper.isArrayLength()) {
            continue;
        }
        final GetFieldChainInliner fieldChainInliner = new GetFieldChainInliner();
        fieldChainInliner.setIterator(iterator);
        fieldChainInliner.setInputObject(instance);
        fieldChainInliner.optimize(original, null);
        if (fieldChainInliner.isOptimized()) {
            optimized = true;
            original.remove(aload);
        }
    }
    return original;
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayValueInliner.java

License:Open Source License

private void replaceNodes(final InsnList newList, final AbstractInsnNode aload, final ArrayHelper arrayHelper,
        final AbstractInsnNode replacementNode, final ListIterator<AbstractInsnNode> iterator) {
    if (replacementNode != null) {
        newList.insert(arrayHelper.getLastLoad(), replacementNode);
    }// w  w w. ja  v a2 s  .  c o m
    newList.remove(aload);
    for (final AbstractInsnNode node : arrayHelper.getIndexes()) {
        newList.remove(node);
    }
    for (final AbstractInsnNode node : arrayHelper.getArrayloads()) {
        newList.remove(node);
    }
    if (replacementNode != null) {
        iterator.next();
    }
    newList.remove(arrayHelper.getFieldNode());
    optimized = true;
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.LocalArrayLengthInliner.java

License:Open Source License

@Override
protected boolean handleValues(final InsnList original, final Map<Integer, Object> knownArrays,
        final AbstractInsnNode currentNode) {
    if (!NodeHelper.isArrayLength(currentNode)) {
        return false;
    }/* w w w .  ja  va2  s  .c  o m*/

    AbstractInsnNode previous = NodeHelper.getPrevious(currentNode);
    final List<AbstractInsnNode> toBeRemoved = new ArrayList<>();
    int index2 = 0;
    while ((previous != null) && !NodeHelper.isAload(previous)) {
        if (NodeHelper.isAAload(previous)) {
            index2 += 1;
        }
        toBeRemoved.add(previous);
        previous = NodeHelper.getPrevious(previous);
    }
    final int index;
    if ((previous != null) && NodeHelper.isAload(previous)) {
        toBeRemoved.add(previous);
        index = ((VarInsnNode) previous).var;
    } else {
        return false;
    }

    final Object array = knownArrays.get(Integer.valueOf(index));
    if ((array == null)) {
        return false;
    }
    Object array2 = array;
    for (int i = 0; i < index2; ++i) {
        array2 = Array.get(array2, i);
    }
    final int arrayLength = Array.getLength(array2);
    original.insertBefore(currentNode, NodeHelper.getInsnNodeFor(arrayLength));

    for (final AbstractInsnNode remove : toBeRemoved) {
        original.remove(remove);
    }
    original.remove(currentNode);
    return true;
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.LocalArrayValueInliner.java

License:Open Source License

@Override
protected boolean handleValues(final InsnList original, final Map<Integer, Object> knownArrays,
        final AbstractInsnNode currentNode) {

    AbstractInsnNode arrayload = currentNode;
    AbstractInsnNode indexNode;/*from ww  w  .jav  a2s  .  co  m*/
    final List<AbstractInsnNode> arrayloads = new ArrayList<>();
    final List<AbstractInsnNode> indexes = new ArrayList<>();
    do {
        if (!Predicates.IS_XALOAD.evaluate(arrayload)) {
            return false;
        }
        arrayloads.add(arrayload);
        indexNode = NodeHelper.getPrevious(arrayload);

        if (!NodeHelper.isNumberNode(indexNode)) {
            return false;
        }
        indexes.add(indexNode);
        arrayload = NodeHelper.getPrevious(indexNode);
        if (arrayload instanceof VarInsnNode) {
            break;
        }
    } while (true);

    final VarInsnNode previous2 = (VarInsnNode) arrayload;

    final Integer varIndex = Integer.valueOf(previous2.var);
    Object array = knownArrays.get(varIndex);

    if (array == null) {
        return false;
    }

    for (int i = indexes.size() - 1; i >= 0; --i) {
        final int indexInArray = NodeHelper.getNumberValue(indexes.get(i)).intValue();
        array = Array.get(array, indexInArray);
    }
    if (!(array instanceof Number)) {
        return false;
    }
    final AbstractInsnNode replacement = NodeHelper.getInsnNodeFor((Number) array);
    original.insertBefore(previous2, replacement);
    for (int i = 0; i < indexes.size(); ++i) {
        original.remove(indexes.get(i));
        original.remove(arrayloads.get(i));
    }
    original.remove(previous2);

    return true;
}

From source file:de.tuberlin.uebb.jbop.optimizer.controlflow.ConstantIfInliner.java

License:Open Source License

private boolean handleNullInstruction(final AbstractInsnNode currentNode, final AbstractInsnNode node1,
        final InsnList list, final Iterator<AbstractInsnNode> iterator) throws JBOPClassException {
    if ((currentNode.getOpcode() == Opcodes.IFNULL) || (currentNode.getOpcode() == Opcodes.IFNONNULL)) {
        final boolean eval;
        if (node1.getOpcode() == Opcodes.ACONST_NULL) {
            if (!checkNullInstruction(node1, currentNode, list, iterator)) {
                return false;
            }/*w w w.  j  a  v a 2 s . c  om*/
            eval = evalSingleOpValue(null, currentNode.getOpcode());
        } else {
            final AbstractInsnNode node2 = NodeHelper.getPrevious(node1);
            if (!checkNumberInstruction(node1, node2, currentNode, list, iterator)) {
                return false;
            }
            // doesn't work for multiarrays yet
            final AbstractInsnNode node3 = NodeHelper.getPrevious(node2);
            final AbstractInsnNode node4 = NodeHelper.getPrevious(node3);
            boolean isNonNullArrayValue = false;
            if (arrayValue != null) {
                for (final NonNullArrayValue nonNullarrayValue : arrayValue.getNonNullArrayValues()) {
                    if (nonNullarrayValue.is(node4, node3, Arrays.asList(node2), Arrays.asList(node1))) {
                        isNonNullArrayValue = true;
                        break;
                    }
                }
            }
            if (!isNonNullArrayValue) {
                return false;
            }
            if (node2 != null) {
                list.remove(node2);
            }
            if (node3 != null) {
                list.remove(node3);
            }
            if (node4 != null) {
                list.remove(node4);
            }
            eval = evalSingleOpValue(NONNULL, currentNode.getOpcode());
        }
        removeNodes(currentNode, node1, null, null, list, iterator, eval);
        return true;
    }
    return false;
}