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:org.epoxide.surge.asm.ASMUtils.java

License:Creative Commons License

/**
 * Removes a specific set of instructions (the needle) from a much larger set of
 * instructions (the hay stack). Be cautious when using this method, as it is almost never
 * a good idea to remove instructions./* w  w  w  . ja  v a  2 s . c  o  m*/
 *
 * @param haystack: A large list of instructions which is being searched through.
 * @param needle: A specific list of instructions which are to be removed from the larger
 *        instruction list.
 */
public static void removeNeedleFromHaystack(InsnList haystack, InsnList needle) {

    final int firstInd = haystack.indexOf(findFirstNodeFromNeedle(haystack, needle));
    final int lastInd = haystack.indexOf(findLastNodeFromNeedle(haystack, needle));
    final List<AbstractInsnNode> realNeedle = new ArrayList<>();

    for (int i = firstInd; i <= lastInd; i++) {
        realNeedle.add(haystack.get(i));
    }

    for (final AbstractInsnNode node : realNeedle) {
        haystack.remove(node);
    }
}

From source file:org.evosuite.instrumentation.ComparisonTransformation.java

License:Open Source License

private void insertLongComparison(AbstractInsnNode position, InsnList list) {
    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "longSub", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.LONG_TYPE, Type.LONG_TYPE }));
    list.insert(position, get);//from ww w  . j  a v a 2 s. c  om
    list.remove(position);
}

From source file:org.evosuite.instrumentation.ComparisonTransformation.java

License:Open Source License

private void insertFloatComparison(AbstractInsnNode position, InsnList list) {
    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "floatSub",
            Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.FLOAT_TYPE, Type.FLOAT_TYPE }));
    list.insert(position, get);/*from  w w  w .  j  a va  2 s .  c o  m*/
    list.remove(position);
}

From source file:org.evosuite.instrumentation.ComparisonTransformation.java

License:Open Source License

private void insertDoubleComparison(AbstractInsnNode position, InsnList list) {
    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "doubleSub",
            Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.DOUBLE_TYPE, Type.DOUBLE_TYPE }));
    list.insert(position, get);/*from www . java  2s.c om*/
    list.remove(position);
}

From source file:org.evosuite.instrumentation.testability.ComparisonTransformation.java

License:Open Source License

private void insertLongComparison(AbstractInsnNode position, InsnList list) {
    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "longSub", Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.LONG_TYPE, Type.LONG_TYPE }),
            false);//from  w  ww  .j  a v  a 2s  .  c o  m
    list.insert(position, get);
    list.remove(position);
}

From source file:org.evosuite.instrumentation.testability.ComparisonTransformation.java

License:Open Source License

private void insertFloatComparisonG(AbstractInsnNode position, InsnList list) {
    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "floatSubG",
            Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.FLOAT_TYPE, Type.FLOAT_TYPE }), false);
    list.insert(position, get);//from w  w  w  . jav  a2  s.c o m
    list.remove(position);
}

From source file:org.evosuite.instrumentation.testability.ComparisonTransformation.java

License:Open Source License

private void insertFloatComparisonL(AbstractInsnNode position, InsnList list) {
    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "floatSubL",
            Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.FLOAT_TYPE, Type.FLOAT_TYPE }), false);
    list.insert(position, get);/*from  ww  w  .  j  a v a2 s .  c o m*/
    list.remove(position);
}

From source file:org.evosuite.instrumentation.testability.ComparisonTransformation.java

License:Open Source License

private void insertDoubleComparisonG(AbstractInsnNode position, InsnList list) {
    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "doubleSubG",
            Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.DOUBLE_TYPE, Type.DOUBLE_TYPE }), false);
    list.insert(position, get);//from   www  .  j av  a 2s . com
    list.remove(position);
}

From source file:org.evosuite.instrumentation.testability.ComparisonTransformation.java

License:Open Source License

private void insertDoubleComparisonL(AbstractInsnNode position, InsnList list) {
    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "doubleSubL",
            Type.getMethodDescriptor(Type.INT_TYPE, new Type[] { Type.DOUBLE_TYPE, Type.DOUBLE_TYPE }), false);
    list.insert(position, get);//www  .  j a v a  2 s  .c o  m
    list.remove(position);
}

From source file:pl.clareo.coroutines.core.MethodTransformer.java

License:Apache License

@SuppressWarnings("unchecked")
MethodNode transform(String coroutineName, boolean generateDebugCode) {
    MethodNode transformedMethod = new MethodNode();
    transformedMethod.access = ACC_PUBLIC | ACC_FINAL | (method.access & ACC_STATIC);
    transformedMethod.name = coroutineName;
    transformedMethod.desc = COROUTINE_METHOD_DESCRIPTOR;
    transformedMethod.exceptions = method.exceptions;
    final InsnList newCode = transformedMethod.instructions;
    Analyzer analyzer = new Analyzer(new BasicInterpreter() {

        @Override/*from ww w .  ja  va2  s.  co m*/
        public Value binaryOperation(AbstractInsnNode insn, Value value1, Value value2)
                throws AnalyzerException {
            if (insn.getOpcode() == AALOAD) {
                return new BasicValue(((BasicValue) value1).getType().getElementType());
            }
            return super.binaryOperation(insn, value1, value2);
        };

        @Override
        public Value merge(Value v, Value w) {
            if (v == NULL_VALUE) {
                BasicValue w1 = (BasicValue) w;
                if (w1.isReference()) {
                    return w1;
                }
            }
            if (w == NULL_VALUE) {
                BasicValue v1 = (BasicValue) v;
                if (v1.isReference())
                    return v1;
            }
            if (!v.equals(w)) {
                BasicValue v1 = (BasicValue) v;
                BasicValue w1 = (BasicValue) w;
                if (v1.isReference() & w1.isReference()) {
                    Class<?> c1;
                    Class<?> c2;
                    try {
                        c1 = MethodTransformer.getClass(v1);
                        c2 = MethodTransformer.getClass(w1);
                    } catch (ClassNotFoundException e) {
                        throw new CoroutineGenerationException(
                                "It was needed to load a class during transformation process but loading unexpectedly failed",
                                e);
                    }
                    if (c1.isAssignableFrom(c2)) {
                        return v;
                    }
                    if (c2.isAssignableFrom(c1)) {
                        return w;
                    }
                }
            } else {
                return v;
            }
            return BasicValue.UNINITIALIZED_VALUE;
        }

        @Override
        public Value newValue(Type type) {
            if (type != null) {
                int typeSort = type.getSort();
                switch (typeSort) {
                case Type.VOID:
                    return NULL_VALUE;
                case Type.BOOLEAN:
                case Type.CHAR:
                case Type.BYTE:
                case Type.SHORT:
                case Type.INT:
                    return BasicValue.INT_VALUE;
                case Type.FLOAT:
                    return BasicValue.FLOAT_VALUE;
                case Type.LONG:
                    return BasicValue.LONG_VALUE;
                case Type.DOUBLE:
                    return BasicValue.DOUBLE_VALUE;
                case Type.ARRAY:
                case Type.OBJECT:
                    if (type.getInternalName().equals("null")) {
                        return NULL_VALUE;
                    }
                    return new BasicValue(type);
                default:
                    throw new Error("Internal error");
                }
            }
            return BasicValue.UNINITIALIZED_VALUE;
        }
    });
    Frame[] frames;
    try {
        frames = analyzer.analyze(methodOwner, method);
    } catch (AnalyzerException e) {
        throw new CoroutineGenerationException(e);
    }
    InsnList code = method.instructions;
    final List<Integer> yields = new ArrayList<Integer>(8);
    /*
     * Copy instructions patching variable indexes and frames, remember
     * yield indexes
     */
    int ic = 0;
    Iterator<AbstractInsnNode> i = code.iterator();
    while (i.hasNext()) {
        AbstractInsnNode insn = i.next();
        switch (insn.getType()) {
        case AbstractInsnNode.FRAME:
            FrameNode frame = (FrameNode) insn.clone(labelsMap);
            // update values
            if (frame.type == F_FULL) {
                if (isStatic) {
                    frame.local.addAll(0, argsStackMapList);
                } else {
                    frame.local.addAll(1, argsStackMapList);
                }
            }
            newCode.add(frame);
            break;
        case AbstractInsnNode.IINC_INSN:
            IincInsnNode iinc = (IincInsnNode) insn.clone(labelsMap);
            iinc.var += variableIndexOffset;
            newCode.add(iinc);
            break;
        case AbstractInsnNode.INSN:
            switch (insn.getOpcode()) {
            case DRETURN:
            case FRETURN:
            case IRETURN:
            case LRETURN:
            case ARETURN:
            case RETURN:
                newCode.add(new InsnNode(POP));
                newCode.add(throwex("java/util/NoSuchElementException"));
                break;
            default:
                newCode.add(insn.clone(labelsMap));
            }
            break;
        case AbstractInsnNode.JUMP_INSN:
            if (insn.getOpcode() == JSR) {
                throw new CoroutineGenerationException("<jsr> not allowed");
            }
            JumpInsnNode jump = (JumpInsnNode) insn;
            LabelNode target = jump.label;
            if (!labelsMap.containsKey(target)) {
                labelsMap.put(target, new LabelNode());
            }
            newCode.add(jump.clone(labelsMap));
            break;
        case AbstractInsnNode.LABEL:
            if (!labelsMap.containsKey(insn)) {
                labelsMap.put((LabelNode) insn, new LabelNode());
            }
            newCode.add(insn.clone(labelsMap));
            break;
        case AbstractInsnNode.METHOD_INSN:
            if (insn.getOpcode() == INVOKESTATIC) {
                MethodInsnNode method = (MethodInsnNode) insn;
                if (method.owner.equals(COROUTINES_NAME)) {
                    String methodName = method.name;
                    if (methodName.equals("_")) {
                        /*
                         * a call to artificial CoIterator, since it is
                         * not needed after instrumentation we replace
                         * it with null. This null will be popped by
                         * corresponding ARETURN. Stack is not changed
                         */
                        newCode.add(new InsnNode(ACONST_NULL));
                        break;
                    }
                    if (methodName.equals("yield")) {
                        /*
                         * a call to yield - core of coroutine
                         * processing
                         */
                        yields.add(ic);
                    }
                }
            }
            newCode.add(insn.clone(labelsMap));
            break;
        case AbstractInsnNode.VAR_INSN:
            if (insn.getOpcode() == RET) {
                throw new CoroutineGenerationException("<ret> not allowed");
            }
            VarInsnNode var = (VarInsnNode) insn.clone(labelsMap);
            if (var.var != 0 || isStatic) {
                var.var += variableIndexOffset;
            }
            newCode.add(var);
            break;
        default:
            newCode.add(insn.clone(labelsMap));
            break;
        }
        ic += 1;
    }
    /*
     * patch yields in transformed code
     */
    final List<LabelNode> gotos = new ArrayList<LabelNode>(9);
    final Set<TryCatchBlockNode> patchedTryCatchBlocks = new HashSet<TryCatchBlockNode>();
    int yieldIndex = 0;
    i = newCode.iterator();
    while (i.hasNext()) {
        AbstractInsnNode insn = i.next();
        /*
         * track locals
         */
        int insnType = insn.getType();
        if (insnType == AbstractInsnNode.VAR_INSN) {
            int opcode = insn.getOpcode();
            if (opcode == ASTORE || opcode == DSTORE || opcode == LSTORE || opcode == ISTORE
                    || opcode == FSTORE) {
                int varIndex = ((VarInsnNode) insn).var - variableIndexOffset;
                finals[varIndex] = false;
            }
            continue;
        }
        /*
         * track line numbers
         */
        if (insnType == AbstractInsnNode.LINE) {
            lineNumber = ((LineNumberNode) insn).line;
            continue;
        }
        if (insnType != AbstractInsnNode.METHOD_INSN) {
            continue;
        }
        MethodInsnNode method = (MethodInsnNode) insn;
        if (!method.owner.equals(COROUTINES_NAME) || !method.name.equals("yield")) {
            continue;
        }
        InsnList yieldCode = new InsnList();
        int index = yields.get(yieldIndex);
        Frame f = frames[index];
        /*
         * a) operand on the top of stack is passed to the caller, we will
         * save it in 'in' parameter OR there is nothing to be passed to the
         * caller in case of yield() overload
         */
        boolean yieldWithArgument = Type.getArgumentTypes(method.desc).length != 0;
        boolean nonemptyStack;
        Type[] stackContents = null;
        int stackTop = 0;
        if (yieldWithArgument) {
            yieldCode.add(input(getStackTop(f)));
            nonemptyStack = f.getStackSize() > 1;
            stackTop = 1;
        } else {
            nonemptyStack = f.getStackSize() > 0;
        }
        /*
         * b) save remaining stack
         */
        if (nonemptyStack) {
            stackContents = getStackContents(f);
            // sanitize stack
            for (Type t : stackContents) {
                if (t == null) {
                    throw new CoroutineGenerationException(
                            "It is not possible to yield with uninitialized memory on the stack. Probably you use construct such as: new A(..,yield,..). Please move this yield call out of constructor");
                }
            }
            yieldCode.add(savestack(frame, stackContents, stackTop));
        }
        /*
         * c) save locals and state
         */
        Type[] locals = getLocals(f);
        yieldCode.add(saveLocals(locals));
        yieldCode.add(new VarInsnNode(ALOAD, frame));
        yieldCode.add(makeInt(++yieldIndex));
        yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "setState", "(I)V"));
        /*
         * d) jump to exit - in debug mode save line number
         */
        if (generateDebugCode) {
            yieldCode.add(new VarInsnNode(ALOAD, frame));
            yieldCode.add(makeInt(lineNumber));
            yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "setLineOfCode", "(I)V"));
        }
        yieldCode.add(new JumpInsnNode(GOTO, yieldLabel));
        /*
         * e) fix jump from switch statement
         */
        LabelNode jump = new LabelNode();
        gotos.add(jump);
        yieldCode.add(jump);
        yieldCode.add(emitCleanFrame());
        /*
         * f) check if exit condition occurs, load locals, restore stack and
         * stack map
         */
        yieldCode.add(new VarInsnNode(ALOAD, frame));
        yieldCode.add(new MethodInsnNode(INVOKEVIRTUAL, FRAME_NAME, "isCoroutineClosed", "()Z"));
        LabelNode continueHere = new LabelNode();
        yieldCode.add(new JumpInsnNode(IFEQ, continueHere));
        yieldCode.add(throwex(COROUTINE_EXIT_EXCEPTION));
        yieldCode.add(continueHere);
        yieldCode.add(new FrameNode(F_SAME, 0, EMPTY_LOCALS, 0, EMPTY_STACK));
        /*
         * find previous frame node, load locals then emit new frame node
         * and load rest
         */
        FrameNode prevFrame = findPreviousFrame(code.get(index));
        Type[] prevLocals;
        if (prevFrame != null) {
            Frame oldFrame = frames[code.indexOf(prevFrame)];
            prevLocals = getLocals(oldFrame);
        } else {
            prevLocals = getLocals(frames[0]);
        }
        yieldCode.add(restoreLocals(prevLocals));
        FrameNode frameNode = mergeFrames(getFrameTypes(prevLocals), null);
        if (frameNode.type != F_SAME) {
            // bug fix - when no locals are restored and the stack is empty
            // two frames are collapsed
            yieldCode.add(frameNode);
        }
        if (nonemptyStack) {
            yieldCode.add(loadstack(frame, stackContents, stackTop));
        }
        // restore temp locals in scope
        yieldCode.add(restoreLocals(diff(locals, prevLocals)));
        /*
         * push "sent" value
         */
        yieldCode.add(new VarInsnNode(ALOAD, out));
        newCode.insertBefore(method, yieldCode);
        /*
         * patch try catch blocks
         */
        List<TryCatchBlockNode> tryCatchBlocks = analyzer.getHandlers(index);
        if (tryCatchBlocks != null) {
            for (TryCatchBlockNode tryCatchBlock : tryCatchBlocks) {
                if (!patchedTryCatchBlocks.contains(tryCatchBlock)) {
                    LabelNode handler = tryCatchBlock.handler;
                    InsnList handlerPatch = new InsnList();
                    String exceptionType = tryCatchBlock.type == null ? "java/lang/Throwable"
                            : tryCatchBlock.type;
                    FrameNode catchFrame = emitCatchFrame(exceptionType);
                    handlerPatch.add(catchFrame);
                    Type[] ls = getLocals(frames[code.indexOf(handler)]);
                    handlerPatch.add(restoreLocals(ls));
                    handlerPatch.add(
                            mergeFrames(getFrameTypes(ls), new Type[] { Type.getObjectType(exceptionType) }));
                    patchedTryCatchBlocks.add(tryCatchBlock);
                    AbstractInsnNode newHandler = labelsMap.get(handler);
                    // remove "real" frame since it is not needed now
                    newCode.remove(findNextFrame(newHandler));
                    newCode.insert(newHandler, handlerPatch);
                }
            }
        }
        newCode.remove(method);
    }
    /*
     * copy local variables (wath out for indices change) and try catch
     * blocks to new method (clone)
     */
    List<TryCatchBlockNode> tryCatchBlocks = method.tryCatchBlocks;
    if (!tryCatchBlocks.isEmpty()) {
        transformedMethod.tryCatchBlocks = new ArrayList<TryCatchBlockNode>(tryCatchBlocks.size());
        for (TryCatchBlockNode tryCatchBlock : tryCatchBlocks) {
            transformedMethod.tryCatchBlocks.add(
                    new TryCatchBlockNode(labelsMap.get(tryCatchBlock.start), labelsMap.get(tryCatchBlock.end),
                            labelsMap.get(tryCatchBlock.handler), tryCatchBlock.type));
        }
    }
    if (method.localVariables != null) {
        List<LocalVariableNode> localVariables = method.localVariables;
        List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>(localVariables.size());
        for (LocalVariableNode localVariable : localVariables) {
            int newIndex = localVariable.index;
            if (newIndex != 0 || isStatic) {
                newIndex += variableIndexOffset;
            }
            newLocalVariables
                    .add(new LocalVariableNode(localVariable.name, localVariable.desc, localVariable.signature,
                            labelsMap.get(localVariable.start), labelsMap.get(localVariable.end), newIndex));
        }
        transformedMethod.localVariables = newLocalVariables;
    }
    newCode.insert(codeBefore(gotos));
    newCode.add(codeAfter());
    return transformedMethod;
}