Example usage for org.apache.commons.bcel6.generic InstructionHandle getInstruction

List of usage examples for org.apache.commons.bcel6.generic InstructionHandle getInstruction

Introduction

In this page you can find the example usage for org.apache.commons.bcel6.generic InstructionHandle getInstruction.

Prototype

public final Instruction getInstruction() 

Source Link

Usage

From source file:daikon.dcomp.StackVer.java

/**
 * Whenever the outgoing frame//from   w w  w .j ava 2 s .  co  m
 * situation of an InstructionContext changes, all its successors are
 * put [back] into the queue [as if they were unvisited].
 * The proof of termination is about the existence of a
 * fix point of frame merging.
 */
private void circulationPump(ControlFlowGraph cfg, InstructionContext start, Frame vanillaFrame,
        InstConstraintVisitor icv, ExecutionVisitor ev) {
    final Random random = new Random();
    InstructionContextQueue icq = new InstructionContextQueue();

    stack_types.set(start.getInstruction().getPosition(), vanillaFrame);
    // new ArrayList() <=>   no Instruction was executed before
    start.execute(vanillaFrame, new ArrayList<InstructionContext>(), icv, ev);
    //   => Top-Level routine (no jsr call before)
    icq.add(start, new ArrayList<InstructionContext>());

    // LOOP!
    while (!icq.isEmpty()) {
        InstructionContext u;
        ArrayList<InstructionContext> ec;
        if (!DEBUG) {
            int r = random.nextInt(icq.size());
            u = icq.getIC(r);
            ec = icq.getEC(r);
            icq.remove(r);
        } else {
            u = icq.getIC(0);
            ec = icq.getEC(0);
            icq.remove(0);
        }

        // this makes Java grumpy
        // ArrayList<InstructionContext> oldchain = (ArrayList<InstructionContext>) (ec.clone());
        ArrayList<InstructionContext> oldchain = new ArrayList<InstructionContext>(ec);
        // this makes Java grumpy
        // ArrayList<InstructionContext> newchain = (ArrayList) (ec.clone());
        ArrayList<InstructionContext> newchain = new ArrayList<InstructionContext>(ec);
        newchain.add(u);

        if ((u.getInstruction().getInstruction()) instanceof RET) {
            // We can only follow _one_ successor, the one after the
            // JSR that was recently executed.
            RET ret = (RET) (u.getInstruction().getInstruction());
            ReturnaddressType t = (ReturnaddressType) u.getOutFrame(oldchain).getLocals().get(ret.getIndex());
            InstructionContext theSuccessor = cfg.contextOf(t.getTarget());

            // Sanity check
            InstructionContext lastJSR = null;
            int skip_jsr = 0;
            for (int ss = oldchain.size() - 1; ss >= 0; ss--) {
                if (skip_jsr < 0) {
                    throw new AssertionViolatedException("More RET than JSR in execution chain?!");
                }
                //System.err.println("+"+oldchain.get(ss));
                if ((oldchain.get(ss)).getInstruction().getInstruction() instanceof JsrInstruction) {
                    if (skip_jsr == 0) {
                        lastJSR = oldchain.get(ss);
                        break;
                    }
                    skip_jsr--;
                }
                if ((oldchain.get(ss)).getInstruction().getInstruction() instanceof RET) {
                    skip_jsr++;
                }
            }
            if (lastJSR == null) {
                throw new AssertionViolatedException(
                        "RET without a JSR before in ExecutionChain?! EC: '" + oldchain + "'.");
            }
            JsrInstruction jsr = (JsrInstruction) (lastJSR.getInstruction().getInstruction());
            if (theSuccessor != (cfg.contextOf(jsr.physicalSuccessor()))) {
                throw new AssertionViolatedException(
                        "RET '" + u.getInstruction() + "' info inconsistent: jump back to '" + theSuccessor
                                + "' or '" + cfg.contextOf(jsr.physicalSuccessor()) + "'?");
            }

            Frame f = u.getOutFrame(oldchain);
            stack_types.set(theSuccessor.getInstruction().getPosition(), f);
            if (theSuccessor.execute(f, newchain, icv, ev)) {
                // This makes 5.0 grumpy: icq.add(theSuccessor, (ArrayList) newchain.clone());
                icq.add(theSuccessor, new ArrayList<InstructionContext>(newchain));
            }
        } else { // "not a ret"

            // Normal successors. Add them to the queue of successors.
            InstructionContext[] succs = u.getSuccessors();
            for (int s = 0; s < succs.length; s++) {
                InstructionContext v = succs[s];
                Frame f = u.getOutFrame(oldchain);
                stack_types.set(v.getInstruction().getPosition(), f);
                if (v.execute(f, newchain, icv, ev)) {
                    // This makes 5.0 grumpy: icq.add(v, (ArrayList) newchain.clone());
                    icq.add(v, new ArrayList<InstructionContext>(newchain));
                }
            }
        } // end "not a ret"

        // Exception Handlers. Add them to the queue of successors.
        // [subroutines are never protected; mandated by JustIce]
        ExceptionHandler[] exc_hds = u.getExceptionHandlers();
        for (int s = 0; s < exc_hds.length; s++) {
            InstructionContext v = cfg.contextOf(exc_hds[s].getHandlerStart());
            // TODO: the "oldchain" and "newchain" is used to determine the subroutine
            // we're in (by searching for the last JSR) by the InstructionContext
            // implementation. Therefore, we should not use this chain mechanism
            // when dealing with exception handlers.
            // Example: a JSR with an exception handler as its successor does not
            // mean we're in a subroutine if we go to the exception handler.
            // We should address this problem later; by now we simply "cut" the chain
            // by using an empty chain for the exception handlers.
            //if (v.execute(new Frame(u.getOutFrame(oldchain).getLocals(), new OperandStack (u.getOutFrame().getStack().maxStack(), (exc_hds[s].getExceptionType()==null? Type.THROWABLE : exc_hds[s].getExceptionType())) ), newchain), icv, ev){
            //icq.add(v, (ArrayList) newchain.clone());
            Frame f = new Frame(u.getOutFrame(oldchain).getLocals(), new OperandStack(
                    u.getOutFrame(oldchain).getStack().maxStack(),
                    (exc_hds[s].getExceptionType() == null ? Type.THROWABLE : exc_hds[s].getExceptionType())));
            stack_types.set(v.getInstruction().getPosition(), f);
            if (v.execute(f, new ArrayList<InstructionContext>(), icv, ev)) {
                icq.add(v, new ArrayList<InstructionContext>());
            }
        }
    } // while (!icq.isEmpty()) END

    InstructionHandle ih = start.getInstruction();
    do {
        if ((ih.getInstruction() instanceof ReturnInstruction) && (!(cfg.isDead(ih)))) {
            InstructionContext ic = cfg.contextOf(ih);
            Frame f = ic.getOutFrame(new ArrayList<InstructionContext>());
            // TODO: This is buggy, we check only the top-level return instructions
            // this way. Maybe some maniac returns from a method when in a subroutine?
            LocalVariables lvs = f.getLocals();
            for (int i = 0; i < lvs.maxLocals(); i++) {
                if (lvs.get(i) instanceof UninitializedObjectType) {
                    this.addMessage("Warning: ReturnInstruction '" + ic
                            + "' may leave method with an uninitialized object in the local variables array '"
                            + lvs + "'.");
                }
            }
            OperandStack os = f.getStack();
            for (int i = 0; i < os.size(); i++) {
                if (os.peek(i) instanceof UninitializedObjectType) {
                    this.addMessage("Warning: ReturnInstruction '" + ic
                            + "' may leave method with an uninitialized object on the operand stack '" + os
                            + "'.");
                }
            }
        }
    } while ((ih = ih.getNext()) != null);
}