Example usage for org.objectweb.asm.tree AbstractInsnNode LABEL

List of usage examples for org.objectweb.asm.tree AbstractInsnNode LABEL

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode LABEL.

Prototype

int LABEL

To view the source code for org.objectweb.asm.tree AbstractInsnNode LABEL.

Click Source Link

Document

The type of LabelNode "instructions".

Usage

From source file:com.lodgon.parboiled.transform.RuleMethodInterpreter.java

License:Open Source License

public void newControlFlowEdge(int instructionIndex, int successorIndex) {
    AbstractInsnNode fromInsn = method.instructions.get(instructionIndex);
    AbstractInsnNode toInsn = method.instructions.get(successorIndex);
    if (fromInsn.getType() == AbstractInsnNode.LABEL || fromInsn.getType() == AbstractInsnNode.JUMP_INSN
            || toInsn.getType() == AbstractInsnNode.LABEL || toInsn.getType() == AbstractInsnNode.JUMP_INSN) {
        additionalEdges.add(new Edge(fromInsn, toInsn));
    }/*w ww  . ja v a2s.  c om*/
}

From source file:com.lodgon.parboiled.transform.UnusedLabelsRemover.java

License:Apache License

@SuppressWarnings({ "SuspiciousMethodCalls" })
public void process(ParserClassNode classNode, RuleMethod method) throws Exception {
    checkArgNotNull(classNode, "classNode");
    checkArgNotNull(method, "method");
    AbstractInsnNode current = method.instructions.getFirst();
    while (current != null) {
        AbstractInsnNode next = current.getNext();
        if (current.getType() == AbstractInsnNode.LABEL && !method.getUsedLabels().contains(current)) {
            method.instructions.remove(current);
        }//  w  ww  .j  a va2s  . c o  m
        current = next;
    }
}

From source file:cz.vutbr.fit.xhriba01.bc.lib.AbstractNodeVisitor.java

License:Open Source License

/**
 * This method detects what type of instruction the NodeInstruction is
 * representing and calls appropriate before/visit/after methods.
 * Subclasses could rather override methods specific for particular
 * instruction type./*from ww w. ja v  a 2s.c  om*/
 * 
 * @param nodeInstruction the instruction node
 */
public void visitNodeInstruction(NodeInstruction nodeInstruction) {
    AbstractInsnNode asmInsn = nodeInstruction.getAsmInsnNode();
    switch (asmInsn.getType()) {
    case AbstractInsnNode.LINE:
        visitLineNumberNode((LineNumberNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LABEL:
        visitLabelNode((LabelNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.FIELD_INSN:
        visitFieldInsn((FieldInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.IINC_INSN:
        visitIincInsn((IincInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INSN:
        visitInsn((InsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INT_INSN:
        visitIntInsn((IntInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        visitInvokeDynamicInsn((InvokeDynamicInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.JUMP_INSN:
        visitJumpInsn((JumpInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LDC_INSN:
        visitLdcInsn((LdcInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN:
        visitLookupSwitchInsn((LookupSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.METHOD_INSN:
        visitMethodInsn((MethodInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN:
        visitMultiANewArrayInsn((MultiANewArrayInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TABLESWITCH_INSN:
        visitTableSwitchInsn((TableSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TYPE_INSN:
        visitTypeInsn((TypeInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.VAR_INSN:
        visitVarInsn((VarInsnNode) asmInsn, nodeInstruction);
        break;
    default:
        // shouldn't happen
        break;
    }
}

From source file:cz.vutbr.fit.xhriba01.bc.lib.AbstractNodeVisitor.java

License:Open Source License

public void afterVisitNodeInstruction(NodeInstruction nodeInstruction) {

    AbstractInsnNode asmInsn = nodeInstruction.getAsmInsnNode();

    switch (asmInsn.getType()) {
    case AbstractInsnNode.LINE:
        afterVisitLineNumberNode((LineNumberNode) asmInsn, nodeInstruction);
        break;/*from www  .j  a va 2  s . com*/
    case AbstractInsnNode.LABEL:
        afterVisitLabelNode((LabelNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.FIELD_INSN:
        afterVisitFieldInsn((FieldInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.IINC_INSN:
        afterVisitIincInsn((IincInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INSN:
        afterVisitInsn((InsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INT_INSN:
        afterVisitIntInsn((IntInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        afterVisitInvokeDynamicInsn((InvokeDynamicInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.JUMP_INSN:
        afterVisitJumpInsn((JumpInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LDC_INSN:
        afterVisitLdcInsn((LdcInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN:
        afterVisitLookupSwitchInsn((LookupSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.METHOD_INSN:
        afterVisitMethodInsn((MethodInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN:
        afterVisitMultiANewArrayInsn((MultiANewArrayInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TABLESWITCH_INSN:
        afterVisitTableSwitchInsn((TableSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TYPE_INSN:
        afterVisitTypeInsn((TypeInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.VAR_INSN:
        afterVisitVarInsn((VarInsnNode) asmInsn, nodeInstruction);
        break;
    default:
        // shouldn't happen
        break;
    }

}

From source file:de.codesourcery.asm.util.Disassembler.java

License:Apache License

private static String disassemble(AbstractInsnNode node, MethodNode method) {
    final int opCode = node.getOpcode();
    String mnemonic = Printer.OPCODES[opCode];

    switch (node.getType()) {
    case AbstractInsnNode.FIELD_INSN: // GETSTATIC, PUTSTATIC, GETFIELD , PUTFIELD
        FieldInsnNode tmp = (FieldInsnNode) node;
        mnemonic += " " + (tmp.owner + "#" + tmp.name);
        break;/*from   w w w  . j  a  va  2s. c  om*/
    case AbstractInsnNode.IINC_INSN: // IINC
        IincInsnNode tmp2 = (IincInsnNode) node;
        mnemonic += " " + (tmp2.var + " , " + tmp2.incr);
        break;
    case AbstractInsnNode.INSN: // regular opcodes
        break;
    case AbstractInsnNode.INT_INSN: // BIPUSH, SIPUSH or NEWARRAY
        IntInsnNode tmp3 = (IntInsnNode) node;
        mnemonic += " " + (tmp3.operand);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN: // INVOKEDYNAMIC
        break;
    case AbstractInsnNode.JUMP_INSN: // IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL
        JumpInsnNode tmp4 = (JumpInsnNode) node;
        int index = method.instructions.indexOf(tmp4.label);
        while (method.instructions.get(index).getOpcode() == -1) {
            index++;
        }
        mnemonic += " " + index;
        break;
    case AbstractInsnNode.LDC_INSN: // load constant
        LdcInsnNode tmp5 = (LdcInsnNode) node;
        Class<?> clazz = tmp5.cst.getClass();
        if (clazz == String.class) {
            mnemonic += " \"" + tmp5.cst + "\"";
        } else if (clazz == org.objectweb.asm.Type.class) {
            org.objectweb.asm.Type type = (org.objectweb.asm.Type) tmp5.cst;
            mnemonic += " (a " + type.getClassName() + ")";
        } else {
            mnemonic += " " + tmp5.cst + " (" + tmp5.cst.getClass().getName() + ")";
        }
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN: // LOOKUPSWITCH
        break;
    case AbstractInsnNode.METHOD_INSN: // INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC , INVOKEINTERFACE
        MethodInsnNode tmp6 = (MethodInsnNode) node;
        mnemonic += " " + (tmp6.owner + "#" + tmp6.name + "()");
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN: // MULTIANEWARRAY
        break;
    case AbstractInsnNode.TABLESWITCH_INSN: // TABLESWITCH
        break;
    case AbstractInsnNode.TYPE_INSN: // NEW, ANEWARRAY, CHECKCAST , INSTANCEOF
        TypeInsnNode tmp8 = (TypeInsnNode) node;
        mnemonic += " " + tmp8.desc;
        break;
    case AbstractInsnNode.VAR_INSN: // ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE , RET
        VarInsnNode tmp7 = (VarInsnNode) node;
        mnemonic += "_" + tmp7.var;
        break;
    // -- VIRTUAL --
    case AbstractInsnNode.FRAME: /* VIRTUAL */
    case AbstractInsnNode.LABEL: /* VIRTUAL */
    case AbstractInsnNode.LINE: /* VIRTUAL */
    default:
        throw new RuntimeException("Internal error, unhandled node type: " + node);
    }
    return mnemonic;
}

From source file:de.unisb.cs.st.javaslicer.tracer.instrumentation.TracingMethodInstrumenter.java

License:Open Source License

@SuppressWarnings("unchecked")
public void transform(final ListIterator<MethodNode> methodIt) {

    // do not modify abstract or native methods
    if ((this.methodNode.access & ACC_ABSTRACT) != 0 || (this.methodNode.access & ACC_NATIVE) != 0)
        return;//from   ww  w.  java2s  .  co m

    // check out what labels are jump targets (only these have to be traced)
    analyze(this.methodNode);

    this.instructionIterator = new FixedInstructionIterator(this.methodNode.instructions);
    // in the old method, initialize the new local variable for the threadtracer
    this.instructionIterator.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Tracer.class),
            "getInstance", "()L" + Type.getInternalName(Tracer.class) + ";", false));
    this.instructionIterator.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Tracer.class),
            "getThreadTracer", "()L" + Type.getInternalName(ThreadTracer.class) + ";", false));
    this.instructionIterator.add(new InsnNode(DUP));
    this.instructionIterator.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));

    this.instructionIterator.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class),
            "isPaused", "()Z", true));
    final LabelNode noTracingLabel = new LabelNode();
    this.instructionIterator.add(new JumpInsnNode(IFNE, noTracingLabel));
    // create a copy of the (uninstrumented) instructions (later, while iterating through the instructions)
    final InsnList oldInstructions = new InsnList();
    final Map<LabelNode, LabelNode> labelCopies = new LazyLabelMap();
    // copy the try-catch-blocks
    final Object[] oldTryCatchblockNodes = this.methodNode.tryCatchBlocks.toArray();
    for (final Object o : oldTryCatchblockNodes) {
        final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
        final TryCatchBlockNode newTcb = new TryCatchBlockNode(labelCopies.get(tcb.start),
                labelCopies.get(tcb.end), labelCopies.get(tcb.handler), tcb.type);
        this.methodNode.tryCatchBlocks.add(newTcb);
    }

    // increment number of local variables by one (for the threadtracer)
    ++this.methodNode.maxLocals;

    // and increment all local variable indexes after the new one by one
    for (final Object o : this.methodNode.localVariables) {
        final LocalVariableNode localVar = (LocalVariableNode) o;
        if (localVar.index >= this.tracerLocalVarIndex)
            ++localVar.index;
    }

    // store information about local variables in the ReadMethod object
    List<LocalVariable> localVariables = new ArrayList<LocalVariable>();
    for (final Object o : this.methodNode.localVariables) {
        final LocalVariableNode localVar = (LocalVariableNode) o;
        while (localVariables.size() <= localVar.index)
            localVariables.add(null);
        localVariables.set(localVar.index, new LocalVariable(localVar.index, localVar.name, localVar.desc));
    }
    this.readMethod.setLocalVariables(localVariables.toArray(new LocalVariable[localVariables.size()]));
    localVariables = null;

    // each method must start with a (dedicated) label:
    assert this.readMethod.getInstructions().isEmpty();
    traceLabel(null, InstructionType.METHODENTRY);
    assert this.readMethod.getInstructions().size() == 1
            && this.readMethod.getInstructions().get(0) instanceof LabelMarker
            && ((LabelMarker) this.readMethod.getInstructions().get(0)).isAdditionalLabel();
    this.readMethod.setMethodEntryLabel((LabelMarker) this.readMethod.getInstructions().get(0));

    // needed later:
    final LabelNode l0 = new LabelNode();
    this.instructionIterator.add(l0);

    // then, visit the instructions that were in the method before
    while (this.instructionIterator.hasNext()) {

        final AbstractInsnNode insnNode = this.instructionIterator.next();
        switch (insnNode.getType()) {
        case AbstractInsnNode.INSN:
            transformInsn((InsnNode) insnNode);
            break;
        case AbstractInsnNode.INT_INSN:
            transformIntInsn((IntInsnNode) insnNode);
            break;
        case AbstractInsnNode.VAR_INSN:
            transformVarInsn((VarInsnNode) insnNode);
            break;
        case AbstractInsnNode.TYPE_INSN:
            transformTypeInsn((TypeInsnNode) insnNode);
            break;
        case AbstractInsnNode.FIELD_INSN:
            transformFieldInsn((FieldInsnNode) insnNode);
            break;
        case AbstractInsnNode.METHOD_INSN:
            transformMethodInsn((MethodInsnNode) insnNode);
            break;
        case AbstractInsnNode.JUMP_INSN:
            transformJumpInsn((JumpInsnNode) insnNode);
            break;
        case AbstractInsnNode.LABEL:
            transformLabel((LabelNode) insnNode);
            break;
        case AbstractInsnNode.LDC_INSN:
            transformLdcInsn((LdcInsnNode) insnNode);
            break;
        case AbstractInsnNode.IINC_INSN:
            transformIincInsn((IincInsnNode) insnNode);
            break;
        case AbstractInsnNode.TABLESWITCH_INSN:
            transformTableSwitchInsn((TableSwitchInsnNode) insnNode);
            break;
        case AbstractInsnNode.LOOKUPSWITCH_INSN:
            transformLookupSwitchInsn((LookupSwitchInsnNode) insnNode);
            break;
        case AbstractInsnNode.MULTIANEWARRAY_INSN:
            transformMultiANewArrayInsn((MultiANewArrayInsnNode) insnNode);
            break;
        case AbstractInsnNode.FRAME:
            // ignore
            break;
        case AbstractInsnNode.LINE:
            // ignore
            break;
        default:
            throw new RuntimeException("Unknown instruction type " + insnNode.getType() + " ("
                    + insnNode.getClass().getSimpleName() + ")");
        }
        oldInstructions.add(insnNode.clone(labelCopies));
    }

    assert this.outstandingInitializations == 0;

    // add the (old) try-catch blocks to the readMethods
    // (can only be done down here since we use the information in the
    // labels map)
    for (final Object o : oldTryCatchblockNodes) {
        final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
        this.readMethod.addTryCatchBlock(new TryCatchBlock(this.labels.get(tcb.start), this.labels.get(tcb.end),
                this.labels.get(tcb.handler), tcb.type));
    }

    final LabelNode l1 = new LabelNode();
    this.instructionIterator.add(l1);
    final int newPos = this.readMethod.getInstructions().size();
    traceLabel(null, InstructionType.METHODEXIT);
    assert this.readMethod.getInstructions().size() == newPos + 1;
    final AbstractInstruction abnormalTerminationLabel = this.readMethod.getInstructions().get(newPos);
    assert abnormalTerminationLabel instanceof LabelMarker;
    this.readMethod.setAbnormalTerminationLabel((LabelMarker) abnormalTerminationLabel);
    this.methodNode.instructions.add(new InsnNode(ATHROW));

    // add a try catch block around the method so that we can trace when this method is left
    // by a thrown exception
    this.methodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, null));

    // now add the code that is executed if no tracing should be performed
    this.methodNode.instructions.add(noTracingLabel);
    if (this.firstLine != -1)
        this.methodNode.instructions.add(new LineNumberNode(this.firstLine, noTracingLabel));
    this.methodNode.instructions.add(new InsnNode(ACONST_NULL));
    this.methodNode.instructions.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));
    this.methodNode.instructions.add(oldInstructions);

    // finally: create a copy of the method that gets the ThreadTracer as argument
    // this is only necessary for private methods or "<init>"
    if (this.tracer.wasRedefined(this.readMethod.getReadClass().getName())
            && (this.methodNode.access & ACC_PRIVATE) != 0) {
        final Type[] oldMethodArguments = Type.getArgumentTypes(this.methodNode.desc);
        final Type[] newMethodArguments = Arrays.copyOf(oldMethodArguments, oldMethodArguments.length + 1);
        newMethodArguments[oldMethodArguments.length] = Type.getType(ThreadTracer.class);
        final String newMethodDesc = Type.getMethodDescriptor(Type.getReturnType(this.methodNode.desc),
                newMethodArguments);
        final MethodNode newMethod = new MethodNode(this.methodNode.access, this.methodNode.name, newMethodDesc,
                this.methodNode.signature,
                (String[]) this.methodNode.exceptions.toArray(new String[this.methodNode.exceptions.size()]));
        methodIt.add(newMethod);

        int threadTracerParamPos = ((this.readMethod.getAccess() & Opcodes.ACC_STATIC) == 0 ? 1 : 0);
        for (final Type t : oldMethodArguments)
            threadTracerParamPos += t.getSize();

        final Map<LabelNode, LabelNode> newMethodLabels = new LazyLabelMap();

        // copy the local variables information to the new method
        for (final Object o : this.methodNode.localVariables) {
            final LocalVariableNode lv = (LocalVariableNode) o;
            newMethod.localVariables.add(new LocalVariableNode(lv.name, lv.desc, lv.signature,
                    newMethodLabels.get(lv.start), newMethodLabels.get(lv.end), lv.index));
        }

        newMethod.maxLocals = this.methodNode.maxLocals;
        newMethod.maxStack = this.methodNode.maxStack;

        // copy the try-catch-blocks
        for (final Object o : this.methodNode.tryCatchBlocks) {
            final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
            newMethod.tryCatchBlocks.add(new TryCatchBlockNode(newMethodLabels.get(tcb.start),
                    newMethodLabels.get(tcb.end), newMethodLabels.get(tcb.handler), tcb.type));
        }

        // skip the first 6 instructions, replace them with these:
        newMethod.instructions.add(new VarInsnNode(ALOAD, threadTracerParamPos));
        newMethod.instructions.add(new InsnNode(DUP));
        newMethod.instructions.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));
        newMethod.instructions.add(new JumpInsnNode(IFNULL, newMethodLabels.get(noTracingLabel)));
        final Iterator<AbstractInsnNode> oldInsnIt = this.methodNode.instructions.iterator(6);
        // and add all the other instructions
        while (oldInsnIt.hasNext()) {
            final AbstractInsnNode insn = oldInsnIt.next();
            newMethod.instructions.add(insn.clone(newMethodLabels));
        }
    }

    ready();
}

From source file:edu.ubc.mirrors.holograms.FrameAnalyzer.java

License:Open Source License

public Frame<FrameValue>[] insertFrames() {
    Frame<FrameValue>[] frames = getFrames();
    if (m == null || m.instructions == null) {
        return frames;
    }/*from   ww  w  . j a v a2s .c o  m*/

    List<Frame<FrameValue>> newFrames = new ArrayList<Frame<FrameValue>>();
    AbstractInsnNode insnNode = m.instructions.getFirst();
    int n = m.instructions.size();
    for (int i = 0; i < n; i++) {
        int insnType = insnNode.getType();
        // Fetch the next node before possibly deleting this one,
        // since that will clear the links.
        AbstractInsnNode nextNode = insnNode.getNext();

        if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE
                || insnType == AbstractInsnNode.FRAME) {
            if (i + 1 < n) {
                jumpIn[i + 1] |= jumpIn[i];
                stepIn[i + 1] = stepIn[i];
            }

            if (insnType == AbstractInsnNode.FRAME) {
                m.instructions.remove(insnNode);
            } else {
                newFrames.add(frames[i]);
            }
        } else {
            if (jumpIn[i] || !stepIn[i]) {
                Frame<FrameValue> frame = frames[i];
                // Unreachable code will have null frames
                if (frame != null) {
                    FrameNode frameNode = toFrameNode(frame);
                    m.instructions.insertBefore(insnNode, frameNode);
                    newFrames.add(newFrame(frame));
                }
            }
            newFrames.add(frames[i]);
        }

        insnNode = nextNode;
    }

    @SuppressWarnings("unchecked")
    Frame<FrameValue>[] result = (Frame<FrameValue>[]) newFrames.toArray(new Frame<?>[newFrames.size()]);
    return result;
}

From source file:io.moshisho.plugins.MyMojo.java

License:Apache License

private static void betterCompile(String classFile) throws IOException {

    InputStream is = new FileInputStream(classFile);
    ClassReader cr = new ClassReader(is);
    is.close();//from   w  w w.j av a2s . c o m
    ClassNode cn = new ClassNode();
    cr.accept(cn, 0);

    List methods = cn.methods;
    for (int i = 0; i < methods.size(); ++i) {
        MethodNode method = (MethodNode) methods.get(i);

        if (!isStaticllyBound(method)) {
            continue;
        }

        InsnList instructions = method.instructions;
        AbstractInsnNode last = instructions.getLast();

        while (last != null && last.getType() == AbstractInsnNode.LABEL) {
            last = last.getPrevious();
        }

        if (last == null || !isReturnInstruction(last)
                || last.getPrevious().getType() != AbstractInsnNode.METHOD_INSN) {
            continue;
        }

        MethodInsnNode methodInv = (MethodInsnNode) last.getPrevious();

        if (!isRecursionCall(cn, method, methodInv)) {
            continue;
        }

        System.out.println("TailRec Optimizaing: " + method.name);

        // get arguments and types
        String methodDesc = method.desc;

        String argsDesc = methodDesc.substring(methodDesc.indexOf('(') + 1, methodDesc.indexOf(')'));
        System.out.println(argsDesc);

        // work with Type.getArgumentTypes
        List<AbstractInsnNode> listInstNodes = new LinkedList<AbstractInsnNode>();
        for (int j = argsDesc.length() - 1; j >= 0; j--) {
            char c = argsDesc.charAt(j);
            switch (c) {
            case 'I':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'Z':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'C':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'B':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'S':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'F':
                listInstNodes.add(new VarInsnNode(FSTORE, argsDesc.length() - j));
                break;
            case 'J':
                listInstNodes.add(new VarInsnNode(LSTORE, argsDesc.length() - j));
                break;
            case 'D':
                listInstNodes.add(new VarInsnNode(DSTORE, argsDesc.length() - j));
                break;
            case '[':
                // TODO:
            case 'L':
                // TODO:
            default:
                System.out.println("NOT TREATING: " + c);
            }

        }

        // remove the last aload_0 of the recursion
        AbstractInsnNode pnt = last;
        while (pnt != null && pnt.getOpcode() != 42
                && !(pnt.getOpcode() == 25 && ((VarInsnNode) pnt).var == 0)) {
            pnt = pnt.getPrevious();
        }
        method.instructions.remove(pnt);

        Collections.reverse(listInstNodes);
        for (AbstractInsnNode abstractInsnNode : listInstNodes) {
            method.instructions.insertBefore(last.getPrevious(), abstractInsnNode);
        }
        // place instead of return //goto

        LabelNode startOfMethodLabel = new LabelNode(new Label());
        method.instructions.insertBefore(method.instructions.getFirst(), startOfMethodLabel);
        JumpInsnNode gotoInst = new JumpInsnNode(GOTO, startOfMethodLabel);
        method.instructions.set(last.getPrevious(), gotoInst);
        method.instructions.remove(last);

        ClassWriter cw = new ClassWriter(0);
        cn.accept(cw);
        FileOutputStream fos = new FileOutputStream(classFile);
        fos.write(cw.toByteArray());
        fos.close();
    }
}

From source file:io.moshisho.plugins.OptimizeClasses.java

License:Apache License

private void optimize(File clz) throws Exception {
    InputStream is = new FileInputStream(clz);
    ClassReader cr = new ClassReader(is);
    is.close();//from   w w w  .ja  v  a  2 s.c o  m
    ClassNode cn = new ClassNode();
    cr.accept(cn, 0);

    List methods = cn.methods;
    for (int i = 0; i < methods.size(); ++i) {
        MethodNode method = (MethodNode) methods.get(i);

        if (!isStaticllyBound(method)) {
            continue;
        }

        InsnList instructions = method.instructions;
        AbstractInsnNode last = instructions.getLast();

        while (last != null && last.getType() == AbstractInsnNode.LABEL) {
            last = last.getPrevious();
        }

        if (last == null || !isReturnInstruction(last)
                || last.getPrevious().getType() != AbstractInsnNode.METHOD_INSN) {
            continue;
        }

        MethodInsnNode methodInv = (MethodInsnNode) last.getPrevious();

        if (!isRecursionCall(cn, method, methodInv)) {
            continue;
        }

        getLog().info("TailRec Optimizaing: " + method.name);

        // get arguments and types
        String methodDesc = method.desc;

        String argsDesc = methodDesc.substring(methodDesc.indexOf('(') + 1, methodDesc.indexOf(')'));
        //System.out.println(argsDesc);

        // work with Type.getArgumentTypes
        List<AbstractInsnNode> listInstNodes = new LinkedList<AbstractInsnNode>();
        for (int j = argsDesc.length() - 1; j >= 0; j--) {
            char c = argsDesc.charAt(j);
            switch (c) {
            case 'I':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'Z':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'C':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'B':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'S':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'F':
                listInstNodes.add(new VarInsnNode(FSTORE, argsDesc.length() - j));
                break;
            case 'J':
                listInstNodes.add(new VarInsnNode(LSTORE, argsDesc.length() - j));
                break;
            case 'D':
                listInstNodes.add(new VarInsnNode(DSTORE, argsDesc.length() - j));
                break;
            case '[':
                // TODO:
            case 'L':
                // TODO:
            default:
                System.out.println("NOT TREATING: " + c);
            }

        }

        // remove the last aload_0 of the recursion
        AbstractInsnNode pnt = last;
        while (pnt != null && pnt.getOpcode() != 42
                && !(pnt.getOpcode() == 25 && ((VarInsnNode) pnt).var == 0)) {
            pnt = pnt.getPrevious();
        }
        method.instructions.remove(pnt);

        Collections.reverse(listInstNodes);
        for (AbstractInsnNode abstractInsnNode : listInstNodes) {
            method.instructions.insertBefore(last.getPrevious(), abstractInsnNode);
        }
        // place instead of return //goto

        LabelNode startOfMethodLabel = new LabelNode(new Label());
        method.instructions.insertBefore(method.instructions.getFirst(), startOfMethodLabel);
        JumpInsnNode gotoInst = new JumpInsnNode(GOTO, startOfMethodLabel);
        method.instructions.set(last.getPrevious(), gotoInst);
        method.instructions.remove(last);

        ClassWriter cw = new ClassWriter(0);
        cn.accept(cw);
        FileOutputStream fos = new FileOutputStream(clz);
        fos.write(cw.toByteArray());
        fos.close();
    }
}

From source file:jaspex.transactifier.ChangeClinitMethodVisitor.java

License:Open Source License

private static boolean clinitIsSafe(Type t) {
    try {/*ww w  .  java2 s  . c  o m*/
        ClassReader cr = new ClassReader(t.commonName());
        ClassNode cNode = new ClassNode();
        cr.accept(cNode, 0);

        for (MethodNode method : cNode.methods) {
            if (!method.name.equals("<clinit>"))
                continue;
            // Examinar instruces
            Iterator<AbstractInsnNode> it = method.instructions.iterator();
            while (it.hasNext()) {
                AbstractInsnNode insn = it.next();
                switch (insn.getType()) {
                case AbstractInsnNode.FRAME:
                case AbstractInsnNode.INT_INSN:
                case AbstractInsnNode.JUMP_INSN:
                case AbstractInsnNode.LABEL:
                case AbstractInsnNode.LDC_INSN:
                case AbstractInsnNode.LINE:
                case AbstractInsnNode.LOOKUPSWITCH_INSN:
                case AbstractInsnNode.MULTIANEWARRAY_INSN:
                case AbstractInsnNode.TABLESWITCH_INSN:
                case AbstractInsnNode.TYPE_INSN:
                case AbstractInsnNode.VAR_INSN:
                    break;
                case AbstractInsnNode.FIELD_INSN:
                    FieldInsnNode fieldInsn = (FieldInsnNode) insn;
                    if (fieldInsn.getOpcode() != PUTSTATIC) {
                        // GETSTATIC, GETFIELD, PUTFIELD
                        return false;
                    }
                    break;
                case AbstractInsnNode.IINC_INSN:
                    return false;
                case AbstractInsnNode.INSN:
                    if (unsafeInsnBytecodes.contains(insn.getOpcode())) {
                        Log.debug(t.commonName() + ".<clinit>() is unsafe " + "because of bytecode "
                                + insn.getOpcode());
                        return false;
                    }
                    break;
                case AbstractInsnNode.METHOD_INSN:
                    MethodInsnNode methodInsn = (MethodInsnNode) insn;
                    if (!ClassFilter.isMethodWhitelisted(Type.fromAsm(methodInsn.owner), methodInsn.name,
                            methodInsn.desc)) {
                        Log.debug(t.commonName() + ".<clinit>() is unsafe " + "because it invokes "
                                + Type.fromAsm(methodInsn.owner).commonName() + "." + methodInsn.name);
                        return false;
                    }
                    break;
                default:
                    throw new Error("Unexpected bytecode " + insn);
                }
            }

            //Log.debug(t.commonName() + ".<clinit>() for " + t + " is safe");
            return true;
        }

        return false;
    } catch (IOException e) {
        throw new Error(e);
    }
}