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

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

Introduction

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

Prototype

int FRAME

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

Click Source Link

Document

The type of FrameNode "instructions".

Usage

From source file:br.usp.each.saeg.badua.core.internal.instr.CoverageMethodTransformer.java

License:Open Source License

@Override
@SuppressWarnings("unchecked")
public void transform(final MethodNode methodNode) {

    final DefUseAnalyzer analyzer = new DefUseAnalyzer();
    try {/* www.j  a va 2  s  .c  o  m*/
        analyzer.analyze(className, methodNode);
    } catch (final AnalyzerException e) {
        throw new RuntimeException(e);
    }

    final DefUseFrame[] frames = analyzer.getDefUseFrames();
    final Variable[] variables = analyzer.getVariables();
    final int[][] successors = analyzer.getSuccessors();
    final int[][] predecessors = analyzer.getPredecessors();
    final int[][] basicBlocks = analyzer.getBasicBlocks();
    final int[] leaders = analyzer.getLeaders();

    final DefUseChain[] chains = DefUseChain.toBasicBlock(
            new DepthFirstDefUseChainSearch().search(frames, variables, successors, predecessors), leaders,
            basicBlocks);

    this.chains = chains;
    if (chains.length == 0)
        return;

    // basic block definitions
    final Set<Variable>[] defs = (Set<Variable>[]) new Set<?>[basicBlocks.length];
    for (int b = 0; b < basicBlocks.length; b++) {
        defs[b] = new HashSet<Variable>();
        for (final int insnIndex : basicBlocks[b]) {
            defs[b].addAll(frames[insnIndex].getDefinitions());
        }
    }

    // bit-sets
    final BitSet[] potcov = new BitSet[basicBlocks.length];
    final BitSet[] potcovpuse = new BitSet[basicBlocks.length];
    final BitSet[] born = new BitSet[basicBlocks.length];
    final BitSet[] disabled = new BitSet[basicBlocks.length];
    final BitSet[] sleepy = new BitSet[basicBlocks.length];
    for (int b = 0; b < basicBlocks.length; b++) {

        potcov[b] = new BitSet(chains.length);
        potcovpuse[b] = new BitSet(chains.length);
        born[b] = new BitSet(chains.length);
        disabled[b] = new BitSet(chains.length);
        sleepy[b] = new BitSet(chains.length);

        for (int i = 0; i < chains.length; i++) {

            final DefUseChain chain = chains[i];

            if (chain.target != -1 ? chain.target == b : chain.use == b) {
                potcov[b].set(i);
                if (chain.target != -1) {
                    potcovpuse[b].set(i);
                }
            }

            if (chain.def == b) {
                born[b].set(i);
            }

            if (chain.def != b && defs[b].contains(variables[chain.var])) {
                disabled[b].set(i);
            }

            if (chain.target != -1) {
                if (chain.use != b) {
                    sleepy[b].set(i);
                }
            }

        }
    }

    // first/last valid instructions
    final AbstractInsnNode[] first = new AbstractInsnNode[basicBlocks.length];
    final AbstractInsnNode[] last = new AbstractInsnNode[basicBlocks.length];
    for (int b = 0; b < basicBlocks.length; b++) {
        for (final int insnIndex : basicBlocks[b]) {
            final AbstractInsnNode insn = methodNode.instructions.get(insnIndex);

            // skip
            switch (insn.getType()) {
            case AbstractInsnNode.LABEL:
            case AbstractInsnNode.FRAME:
            case AbstractInsnNode.LINE:
                continue;
            }

            if (first[b] == null) {
                first[b] = insn;
            }
            last[b] = insn;
        }
    }

    AbstractInsnNode insn = methodNode.instructions.getFirst();
    final int windows = (chains.length + 63) / 64;
    final int[] indexes = new int[windows];
    for (int w = 0; w < windows; w++) {
        indexes[w] = idGen.nextId();
        LabelFrameNode.insertBefore(insn, methodNode.instructions, init(methodNode, w));
    }

    for (int b = 0; b < basicBlocks.length; b++) {

        final long[] lPotcov = BitSetUtils.toLongArray(potcov[b], windows);
        final long[] lPotcovpuse = BitSetUtils.toLongArray(potcovpuse[b], windows);
        final long[] lBorn = BitSetUtils.toLongArray(born[b], windows);
        final long[] lDisabled = BitSetUtils.toLongArray(disabled[b], windows);
        final long[] lSleepy = BitSetUtils.toLongArray(sleepy[b], windows);

        for (int w = 0; w < windows; w++) {

            final int nPredecessors = predecessors[basicBlocks[b][0]].length;
            final Probe p = probe(methodNode, w, nPredecessors == 0);

            p.potcov = lPotcov[w];
            p.potcovpuse = lPotcovpuse[w];
            p.born = lBorn[w];
            p.disabled = lDisabled[w];
            p.sleepy = lSleepy[w];
            p.singlePredecessor = nPredecessors == 1;

            LabelFrameNode.insertBefore(first[b], methodNode.instructions, p);

        }
        if (isReturn(last[b].getOpcode())) {
            for (int w = 0; w < windows; w++) {
                final Probe p = update(methodNode, w, indexes[w]);
                LabelFrameNode.insertBefore(last[b], methodNode.instructions, p);
            }
        }
    }

    // Finally, update the frames
    while (insn != null) {
        if (insn instanceof FrameNode) {
            final FrameNode frame = (FrameNode) insn;
            frame.local = new ArrayList<Object>(frame.local);
            int size = 0;
            for (final Object obj : frame.local) {
                size++;
                if (obj.equals(Opcodes.DOUBLE) || obj.equals(Opcodes.LONG)) {
                    size++;
                }
            }
            while (size < methodNode.maxLocals) {
                frame.local.add(Opcodes.TOP);
                size++;
            }
            final Integer type = typeOfVars();
            for (int i = 0; i < windows; i++) {
                frame.local.add(type);
                frame.local.add(type);
                frame.local.add(type);
            }
        }
        insn = insn.getNext();
    }

    methodNode.maxLocals = methodNode.maxLocals + windows * numOfVars();
    methodNode.maxStack = methodNode.maxStack + 6;
}

From source file:br.usp.each.saeg.badua.core.internal.instr.LabelFrameNode.java

License:Open Source License

private static LabelFrameNode create(final AbstractInsnNode location) {
    AbstractInsnNode insn = location.getPrevious();
    if (insn == null) {
        return null;
    }//from www.  j ava  2 s.c  o  m
    while (true) {
        switch (insn.getType()) {
        case AbstractInsnNode.LABEL:
            return create((LabelFrameNode) insn);
        case AbstractInsnNode.FRAME:
        case AbstractInsnNode.LINE:
            insn = insn.getPrevious();
            continue;
        default:
            return null;
        }
    }
}

From source file:cl.inria.stiq.instrumenter.BCIUtils.java

License:Open Source License

private static void printFrames(MethodNode aNode, Frame[] aFrames) {
    int bcIndex = 1;

    for (int i = 0; i < aFrames.length; i++) {
        Frame theFrame = aFrames[i];
        AbstractInsnNode theInsn = aNode.instructions.get(i);

        switch (theInsn.getType()) {
        case AbstractInsnNode.INSN:
        case AbstractInsnNode.INT_INSN:
        case AbstractInsnNode.VAR_INSN:
        case AbstractInsnNode.TYPE_INSN:
        case AbstractInsnNode.FIELD_INSN:
        case AbstractInsnNode.METHOD_INSN:
        case AbstractInsnNode.JUMP_INSN:
        case AbstractInsnNode.LDC_INSN:
        case AbstractInsnNode.IINC_INSN:
        case AbstractInsnNode.TABLESWITCH_INSN:
        case AbstractInsnNode.LOOKUPSWITCH_INSN:
        case AbstractInsnNode.MULTIANEWARRAY_INSN:
            TraceMethodVisitor theTraceVisitor = new TraceMethodVisitor();
            theInsn.accept(theTraceVisitor);
            StringWriter theWriter = new StringWriter();
            theTraceVisitor.print(new PrintWriter(theWriter));
            String theTraced = theWriter.toString().replace("\n", "");
            System.out.println(bcIndex + "\t" + frameString(theFrame) + " |\t" + theTraced);
            bcIndex++;//from www .  java 2 s .c o m
            break;

        case AbstractInsnNode.FRAME:
        case AbstractInsnNode.LINE:
        case AbstractInsnNode.LABEL:
            break;
        }
    }
}

From source file:com.android.tools.klint.detector.api.LintUtils.java

License:Apache License

/**
 * Returns the previous instruction prior to the given node, ignoring label
 * and line number nodes.//from   w  w w  . j  av  a  2  s  .c  o m
 *
 * @param node the node to look up the previous instruction for
 * @return the previous instruction, or null if no previous node was found
 */
@Nullable
public static AbstractInsnNode getPrevInstruction(@NonNull AbstractInsnNode node) {
    AbstractInsnNode prev = node;
    while (true) {
        prev = prev.getPrevious();
        if (prev == null) {
            return null;
        } else {
            int type = prev.getType();
            if (type != AbstractInsnNode.LINE && type != AbstractInsnNode.LABEL
                    && type != AbstractInsnNode.FRAME) {
                return prev;
            }
        }
    }
}

From source file:com.android.tools.klint.detector.api.LintUtils.java

License:Apache License

/**
 * Returns the next instruction after to the given node, ignoring label and
 * line number nodes.//from w ww. j  av  a  2  s  .c  om
 *
 * @param node the node to look up the next node for
 * @return the next instruction, or null if no next node was found
 */
@Nullable
public static AbstractInsnNode getNextInstruction(@NonNull AbstractInsnNode node) {
    AbstractInsnNode next = node;
    while (true) {
        next = next.getNext();
        if (next == null) {
            return null;
        } else {
            int type = next.getType();
            if (type != AbstractInsnNode.LINE && type != AbstractInsnNode.LABEL
                    && type != AbstractInsnNode.FRAME) {
                return next;
            }
        }
    }
}

From source file:com.android.tools.lint.checks.WakelockDetector.java

License:Apache License

/** Search from the given node towards the target; return false if we reach
 * an exit point such as a return or a call on the way there that is not within
 * a try/catch clause./* w  w w  . ja v  a  2 s .  com*/
 *
 * @param node the current node
 * @return true if the target was reached
 *    XXX RETURN VALUES ARE WRONG AS OF RIGHT NOW
 */
protected int dfs(ControlFlowGraph.Node node) {
    AbstractInsnNode instruction = node.instruction;
    if (instruction.getType() == AbstractInsnNode.JUMP_INSN) {
        int opcode = instruction.getOpcode();
        if (opcode == Opcodes.RETURN || opcode == Opcodes.ARETURN || opcode == Opcodes.LRETURN
                || opcode == Opcodes.IRETURN || opcode == Opcodes.DRETURN || opcode == Opcodes.FRETURN
                || opcode == Opcodes.ATHROW) {
            if (DEBUG) {
                System.out.println("Found exit via explicit return: " //$NON-NLS-1$
                        + node.toString(false));
            }
            return SEEN_RETURN;
        }
    }

    if (!DEBUG) {
        // There are no cycles, so no *NEED* for this, though it does avoid
        // researching shared labels. However, it makes debugging harder (no re-entry)
        // so this is only done when debugging is off
        if (node.visit != 0) {
            return 0;
        }
        node.visit = 1;
    }

    // Look for the target. This is any method call node which is a release on the
    // lock (later also check it's the same instance, though that's harder).
    // This is because finally blocks tend to be inlined so from a single try/catch/finally
    // with a release() in the finally, the bytecode can contain multiple repeated
    // (inlined) release() calls.
    if (instruction.getType() == AbstractInsnNode.METHOD_INSN) {
        MethodInsnNode method = (MethodInsnNode) instruction;
        if (method.name.equals(RELEASE_METHOD) && method.owner.equals(WAKELOCK_OWNER)) {
            return SEEN_TARGET;
        } else if (method.name.equals(ACQUIRE_METHOD) && method.owner.equals(WAKELOCK_OWNER)) {
            // OK
        } else if (method.name.equals(IS_HELD_METHOD) && method.owner.equals(WAKELOCK_OWNER)) {
            // OK
        } else {
            // Some non acquire/release method call: if this is not associated with a
            // try-catch block, it would mean the exception would exit the method,
            // which would be an error
            if (node.exceptions == null || node.exceptions.isEmpty()) {
                // Look up the corresponding frame, if any
                AbstractInsnNode curr = method.getPrevious();
                boolean foundFrame = false;
                while (curr != null) {
                    if (curr.getType() == AbstractInsnNode.FRAME) {
                        foundFrame = true;
                        break;
                    }
                    curr = curr.getPrevious();
                }

                if (!foundFrame) {
                    if (DEBUG) {
                        System.out.println("Found exit via unguarded method call: " //$NON-NLS-1$
                                + node.toString(false));
                    }
                    return SEEN_RETURN;
                }
            }
        }
    }

    // if (node.instruction is a call, and the call is not caught by
    // a try/catch block (provided the release is not inside the try/catch block)
    // then return false
    int status = 0;

    boolean implicitReturn = true;
    List<Node> successors = node.successors;
    List<Node> exceptions = node.exceptions;
    if (exceptions != null) {
        if (!exceptions.isEmpty()) {
            implicitReturn = false;
        }
        for (Node successor : exceptions) {
            status = dfs(successor) | status;
            if ((status & SEEN_RETURN) != 0) {
                if (DEBUG) {
                    System.out.println("Found exit via exception: " //$NON-NLS-1$
                            + node.toString(false));
                }
                return status;
            }
        }

        if (status != 0) {
            status |= SEEN_EXCEPTION;
        }
    }

    if (successors != null) {
        if (!successors.isEmpty()) {
            implicitReturn = false;
            if (successors.size() > 1) {
                status |= SEEN_BRANCH;
            }
        }
        for (Node successor : successors) {
            status = dfs(successor) | status;
            if ((status & SEEN_RETURN) != 0) {
                if (DEBUG) {
                    System.out.println("Found exit via branches: " //$NON-NLS-1$
                            + node.toString(false));
                }
                return status;
            }
        }
    }

    if (implicitReturn) {
        status |= SEEN_RETURN;
        if (DEBUG) {
            System.out.println("Found exit: via implicit return: " //$NON-NLS-1$
                    + node.toString(false));
        }
    }

    return status;
}

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 www . j  a v a  2  s  .  c o m*/
    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  w  ww.  j a v  a 2s . c  o  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;
    }//  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:jaspex.transactifier.ChangeClinitMethodVisitor.java

License:Open Source License

private static boolean clinitIsSafe(Type t) {
    try {/*from  w  ww  .  ja  v  a2  s  .  co 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);
    }
}