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

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

Introduction

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

Prototype

@Override
public ListIterator<AbstractInsnNode> iterator() 

Source Link

Document

Returns an iterator over the instructions in this list.

Usage

From source file:org.evosuite.setup.PutStaticMethodCollector.java

License:Open Source License

@SuppressWarnings("unchecked")
public Set<MethodIdentifier> collectMethods() {

    Set<MethodIdentifier> methods = new LinkedHashSet<MethodIdentifier>();

    for (String calledClassName : getStaticFields.keySet()) {
        ClassNode classNode = DependencyAnalysis.getClassNode(calledClassName);
        List<MethodNode> classMethods = classNode.methods;
        for (MethodNode mn : classMethods) {
            if (mn.name.equals(CLINIT))
                continue;

            InsnList instructions = mn.instructions;
            Iterator<AbstractInsnNode> it = instructions.iterator();
            while (it.hasNext()) {
                AbstractInsnNode insn = it.next();
                if (insn instanceof FieldInsnNode) {
                    FieldInsnNode fieldInsn = (FieldInsnNode) insn;
                    if (fieldInsn.getOpcode() != Opcodes.PUTSTATIC) {
                        continue;
                    }//from ww w . j a  v a  2 s  . c  om
                    String calleeClassName = fieldInsn.owner.replaceAll("/", ".");
                    String calleeFieldName = fieldInsn.name;

                    if (contains(getStaticFields, calleeClassName, calleeFieldName)) {

                        MethodIdentifier methodIdentifier = new MethodIdentifier(calledClassName, mn.name,
                                mn.desc);
                        methods.add(methodIdentifier);

                    }
                }
            }

        }

    }
    return methods;
}

From source file:org.lambdamatic.analyzer.ast.InsnCursor.java

License:Open Source License

/**
 * Constructor/*  ww w .j  a  v a  2  s.c o m*/
 * 
 * @param instructions the {@link InsnList} to iterate on.
 * @param labels the labels to locate specific instructions.
 */
@SuppressWarnings("unchecked")
public InsnCursor(final InsnList instructions, final Map<String, AbstractInsnNode> labels) {
    this.instructions = instructions;
    this.iterator = instructions.iterator();
    this.labels = labels;
}

From source file:org.qkit.core.asm.adapters.ChangeSuperclassAdapter.java

License:Open Source License

@Override
public void visitEnd() {
    ClassNode cn = (ClassNode) cv;/*from  w  w w.  j  a  v a2s .co m*/

    for (MethodNode mn : cn.methods) {
        InsnList il = mn.instructions;
        Iterator<AbstractInsnNode> it = il.iterator();

        while (it.hasNext()) {
            AbstractInsnNode ain = it.next();

            if (ain instanceof MethodInsnNode) {
                MethodInsnNode m = (MethodInsnNode) ain;
                if ((m.getOpcode() == INVOKESPECIAL)) {
                    MethodInsnNode min = (MethodInsnNode) ain;
                    if (min.owner.equals(cn.superName)) {
                        min.owner = superClass;
                    }
                    break;
                }
            }
        }
    }

    cn.superName = superClass;

    System.out.println("    [~S] " + cn.name + " extends " + cn.superName);

    cn.accept(next);

}

From source file:org.spongepowered.asm.mixin.injection.points.BeforeInvoke.java

License:MIT License

@Override
public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) {
    int ordinal = 0;
    boolean found = false;

    if (this.logging) {
        this.logger.info("{} is searching for an injection point in method with descriptor {}", this.className,
                desc);/*w w  w  .  j  av a2s  .c  o  m*/
    }

    ListIterator<AbstractInsnNode> iter = insns.iterator();
    while (iter.hasNext()) {
        AbstractInsnNode insn = iter.next();

        if (this.matchesInsn(insn)) {
            MemberInfo nodeInfo = new MemberInfo(insn);

            if (this.logging) {
                this.logger.info("{} is considering insn {}", this.className, nodeInfo);
            }

            if (this.target.matches(nodeInfo.owner, nodeInfo.name, nodeInfo.desc)) {
                if (this.logging) {
                    this.logger.info("{} > found a matching insn, checking preconditions...", this.className);
                }

                if (this.matchesInsn(nodeInfo, ordinal)) {
                    if (this.logging) {
                        this.logger.info("{} > > > found a matching insn at ordinal {}", this.className,
                                ordinal);
                    }

                    nodes.add(insn);
                    found = true;

                    if (this.ordinal == ordinal) {
                        break;
                    }
                }

                ordinal++;
            }
        }

        this.inspectInsn(desc, insns, insn);
    }

    return found;
}

From source file:org.spongepowered.asm.mixin.injection.points.BeforeNew.java

License:MIT License

@Override
public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) {
    boolean found = false;
    int ordinal = 0;

    ListIterator<AbstractInsnNode> iter = insns.iterator();
    while (iter.hasNext()) {
        AbstractInsnNode insn = iter.next();

        if (insn instanceof TypeInsnNode && insn.getOpcode() == Opcodes.NEW
                && this.matchesOwner((TypeInsnNode) insn)) {
            if (this.ordinal == -1 || this.ordinal == ordinal) {
                nodes.add(insn);//w  w  w.  j  ava  2  s. com
                found = true;
            }

            ordinal++;
        }
    }

    return found;
}

From source file:org.spongepowered.asm.mixin.injection.points.BeforeReturn.java

License:MIT License

@Override
public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) {
    boolean found = false;

    // RETURN opcode varies based on return type, thus we calculate what opcode we're actually looking for by inspecting the target method
    int returnOpcode = Type.getReturnType(desc).getOpcode(Opcodes.IRETURN);
    int ordinal = 0;

    ListIterator<AbstractInsnNode> iter = insns.iterator();
    while (iter.hasNext()) {
        AbstractInsnNode insn = iter.next();

        if (insn instanceof InsnNode && insn.getOpcode() == returnOpcode) {
            if (this.ordinal == -1 || this.ordinal == ordinal) {
                nodes.add(insn);//  w  w w.ja v  a  2  s. co m
                found = true;
            }

            ordinal++;
        }
    }

    return found;
}

From source file:org.spongepowered.asm.mixin.injection.points.JumpInsnPoint.java

License:MIT License

@Override
public boolean find(String desc, InsnList insns, Collection<AbstractInsnNode> nodes) {
    boolean found = false;
    int ordinal = 0;

    ListIterator<AbstractInsnNode> iter = insns.iterator();
    while (iter.hasNext()) {
        AbstractInsnNode insn = iter.next();

        if (insn instanceof JumpInsnNode && (this.opCode == -1 || insn.getOpcode() == this.opCode)) {
            if (this.ordinal == -1 || this.ordinal == ordinal) {
                nodes.add(insn);/*from   w  w w.  j  ava2  s .  c  o m*/
                found = true;
            }

            ordinal++;
        }
    }

    return found;
}

From source file:org.spongepowered.despector.ast.io.insn.OpcodeDecompiler.java

License:Open Source License

private void buildIntermediates(InsnList instructions, Locals locals) {
    this.instructions = Lists.newArrayList();
    Iterator<AbstractInsnNode> it = instructions.iterator();
    while (it.hasNext()) {
        AbstractInsnNode next = it.next();
        this.instructions.add(next);
    }/*from  w w w  .j ava2s.  c  o  m*/
    intermediate_stack = false;
    for (this.instructions_index = 0; this.instructions_index < this.instructions.size();) {
        AbstractInsnNode next = this.instructions.get(this.instructions_index++);
        //            System.out.println(AstUtil.insnToString(next));
        handleIntermediate(next);
    }
}

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 w w w  .  j  av a  2s  .  c  om
        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;
}

From source file:the.bytecode.club.bytecodeviewer.searching.FieldCallSearch.java

License:Open Source License

@Override
public void search(final ClassNode node, final SearchResultNotifier srn, boolean exact) {
    final Iterator<MethodNode> methods = node.methods.iterator();
    String owner = mOwner.getText();
    if (owner.isEmpty()) {
        owner = null;/*w w  w . ja  v a  2s.  com*/
    }
    String name = mName.getText();
    if (name.isEmpty()) {
        name = null;
    }
    String desc = mDesc.getText();
    if (desc.isEmpty()) {
        desc = null;
    }
    while (methods.hasNext()) {
        final MethodNode method = methods.next();

        final InsnList insnlist = method.instructions;
        final ListIterator<AbstractInsnNode> instructions = insnlist.iterator();
        while (instructions.hasNext()) {
            final AbstractInsnNode insnNode = instructions.next();
            if (insnNode instanceof FieldInsnNode) {
                final FieldInsnNode min = (FieldInsnNode) insnNode;
                if (name == null && owner == null && desc == null)
                    continue;
                if (exact) {
                    if (name != null && !name.equals(min.name)) {
                        continue;
                    }
                    if (owner != null && !owner.equals(min.owner)) {
                        continue;
                    }
                    if (desc != null && !desc.equals(min.desc)) {
                        continue;
                    }
                    String desc2 = method.desc;
                    try {
                        desc2 = Type.getType(method.desc).toString();
                        if (desc2 == null || desc2.equals("null"))
                            desc2 = method.desc;
                    } catch (java.lang.ArrayIndexOutOfBoundsException e) {

                    }
                    srn.notifyOfResult(node.name + "." + method.name + desc2 + " > "
                            + OpcodeInfo.OPCODES.get(insnNode.opcode()).toLowerCase());
                } else {

                    if (name != null && !min.name.contains(name)) {
                        continue;
                    }
                    if (owner != null && !min.owner.contains(owner)) {
                        continue;
                    }
                    if (desc != null && !min.desc.contains(desc)) {
                        continue;
                    }
                    String desc2 = method.desc;
                    try {
                        desc2 = Type.getType(method.desc).toString();
                        if (desc2 == null || desc2.equals("null"))
                            desc2 = method.desc;
                    } catch (java.lang.ArrayIndexOutOfBoundsException e) {

                    }
                    srn.notifyOfResult(node.name + "." + method.name + desc2 + " > "
                            + OpcodeInfo.OPCODES.get(insnNode.opcode()).toLowerCase());
                }
            }
        }

    }
}