org.apache.bcel.generic.MethodGen - java examples

Here are the examples of the java api org.apache.bcel.generic.MethodGen taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.

145 Examples 7

19 View Complete Implementation : ResourceValueAnalysis.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
@javax.annotation.ParametersAreNonnullByDefault
public clreplaced ResourceValuereplacedysis<Resource> extends FrameDataflowreplacedysis<ResourceValue, ResourceValueFrame> implements EdgeTypes {

    private static final boolean DEBUG = SystemProperties.getBoolean("dataflow.debug");

    private final MethodGen methodGen;

    private final CFG cfg;

    private final ResourceTracker<Resource> resourceTracker;

    private final Resource resource;

    private final ResourceValueFrameModelingVisitor visitor;

    private final boolean ignoreImplicitExceptions;

    public ResourceValuereplacedysis(MethodGen methodGen, CFG cfg, DepthFirstSearch dfs, ResourceTracker<Resource> resourceTracker, Resource resource) {
        super(dfs);
        this.methodGen = methodGen;
        this.cfg = cfg;
        this.resourceTracker = resourceTracker;
        this.resource = resource;
        this.visitor = resourceTracker.createVisitor(resource, methodGen.getConstantPool());
        this.ignoreImplicitExceptions = resourceTracker.ignoreImplicitExceptions(resource);
    }

    @Override
    public ResourceValueFrame createFact() {
        ResourceValueFrame fact = new ResourceValueFrame(methodGen.getMaxLocals());
        fact.setTop();
        return fact;
    }

    @Override
    public void initEntryFact(ResourceValueFrame result) {
        result.setValid();
        result.clearStack();
        final int numSlots = result.getNumSlots();
        for (int i = 0; i < numSlots; ++i) {
            boolean slotContainsInstance = resourceTracker.isParamInstance(resource, i);
            result.setValue(i, slotContainsInstance ? ResourceValue.instance() : ResourceValue.notInstance());
        }
    }

    @Override
    public void meetInto(ResourceValueFrame fact, Edge edge, ResourceValueFrame result) throws DataflowreplacedysisException {
        BasicBlock source = edge.getSource();
        BasicBlock dest = edge.getTarget();
        ResourceValueFrame tmpFact = null;
        if (edge.isExceptionEdge()) {
            // If this edge throws only implicit exceptions
            // (as determined by Typereplacedysis and
            // PruneInfeasibleExceptionEdges),
            // and the resource tracker says to ignore implicit exceptions
            // for this resource, ignore it.
            if (replacedysisContext.currentreplacedysisContext().getBoolProperty(replacedysisFeatures.ACCURATE_EXCEPTIONS) && ignoreImplicitExceptions && !edge.isFlagSet(EXPLICIT_EXCEPTIONS_FLAG)) {
                return;
            }
            // The ResourceTracker may veto the exception edge
            if (resourceTracker.ignoreExceptionEdge(edge, resource, methodGen.getConstantPool())) {
                return;
            }
            if (fact.getStatus() == ResourceValueFrame.OPEN) {
                // If status is OPEN, downgrade to OPEN_ON_EXCEPTION_PATH
                tmpFact = modifyFrame(fact, null);
                tmpFact.setStatus(ResourceValueFrame.OPEN_ON_EXCEPTION_PATH);
            }
            if (fact.isValid()) {
                // Special case: if the instruction that closes the resource
                // throws an exception, we consider the resource to be
                // successfully
                // closed anyway.
                InstructionHandle exceptionThrower = source.getExceptionThrower();
                BasicBlock fallThroughSuccessor = cfg.getSuccessorWithEdgeType(source, FALL_THROUGH_EDGE);
                if (DEBUG && fallThroughSuccessor == null) {
                    System.out.println("Null fall through successor!");
                }
                if (fallThroughSuccessor != null && resourceTracker.isResourceClose(fallThroughSuccessor, exceptionThrower, methodGen.getConstantPool(), resource, fact)) {
                    tmpFact = modifyFrame(fact, tmpFact);
                    tmpFact.setStatus(ResourceValueFrame.CLOSED);
                    if (DEBUG) {
                        System.out.print("(failed attempt to close)");
                    }
                }
            }
            if (dest.isExceptionHandler()) {
                // Clear stack, push value for exception
                if (fact.isValid()) {
                    tmpFact = modifyFrame(fact, tmpFact);
                    tmpFact.clearStack();
                    tmpFact.pushValue(ResourceValue.notInstance());
                }
            }
        }
        // Make the resource nonexistent if it is compared against null
        int edgeType = edge.getType();
        if (edgeType == IFCMP_EDGE || edgeType == FALL_THROUGH_EDGE) {
            InstructionHandle lastInSourceHandle = source.getLastInstruction();
            if (lastInSourceHandle != null) {
                Instruction lastInSource = lastInSourceHandle.getInstruction();
                boolean isNullCheck = false;
                boolean isNonNullCheck = false;
                // This check catches null == X, null != X
                if (lastInSource instanceof IF_ACMPEQ || lastInSource instanceof IF_ACMPNE) {
                    Location l = new Location(lastInSourceHandle, source);
                    InstructionHandle ih = l.getHandle();
                    // Get instruction that pushed topmost
                    InstructionHandle ihPrev = ih.getPrev();
                    // Get next-topmost that pushed next-topmost
                    InstructionHandle ihPrevPrev = ihPrev == null ? null : ihPrev.getPrev();
                    int prevPush = 0;
                    if (ihPrev != null) {
                        prevPush = ihPrev.getInstruction().produceStack(methodGen.getConstantPool());
                    }
                    int prevPrevPush = 0;
                    if (ihPrevPrev != null) {
                        prevPrevPush = ihPrevPrev.getInstruction().produceStack(methodGen.getConstantPool());
                    }
                    // If instructions exist and both push one word onto the
                    // stack and the next-topmost pushes null...
                    if (ihPrev != null && ihPrevPrev != null && prevPush == 1 && prevPrevPush == 1 && ihPrevPrev.getInstruction().getOpcode() == Const.ACONST_NULL) {
                        // Topmost item on stack is being compared with null
                        // (the null itself is next-topmost on the stack)
                        isNullCheck = lastInSource instanceof IF_ACMPEQ;
                        isNonNullCheck = lastInSource instanceof IF_ACMPNE;
                    }
                } else // This check catches X == null, X != null
                if (lastInSource instanceof IFNULL || lastInSource instanceof IFNONNULL) {
                    isNullCheck = lastInSource instanceof IFNULL;
                    isNonNullCheck = lastInSource instanceof IFNONNULL;
                }
                if (isNullCheck || isNonNullCheck) {
                    // Get the frame at the if statement
                    ResourceValueFrame startFrame = getStartFact(source);
                    if (startFrame.isValid()) {
                        // The source block has a valid start fact.
                        // That means it is safe to inspect the frame at the If
                        // instruction.
                        ResourceValueFrame frameAtIf = getFactAtLocation(new Location(lastInSourceHandle, source));
                        ResourceValue topValue = frameAtIf.getValue(frameAtIf.getNumSlots() - 1);
                        if (topValue.isInstance()) {
                            if ((isNullCheck && edgeType == IFCMP_EDGE) || (isNonNullCheck && edgeType == FALL_THROUGH_EDGE)) {
                                // System.out.println("**** making resource nonexistent on edge "+edge.getId());
                                tmpFact = modifyFrame(fact, tmpFact);
                                tmpFact.setStatus(ResourceValueFrame.NONEXISTENT);
                            }
                        }
                    }
                }
            }
        }
        if (tmpFact != null) {
            fact = tmpFact;
        }
        mergeInto(fact, result);
    }

    @Override
    protected void mergeInto(ResourceValueFrame frame, ResourceValueFrame result) throws DataflowreplacedysisException {
        // Merge slots
        super.mergeInto(frame, result);
        // Merge status
        result.setStatus(Math.min(result.getStatus(), frame.getStatus()));
    }

    @Override
    protected void mergeValues(ResourceValueFrame otherFrame, ResourceValueFrame resultFrame, int slot) throws DataflowreplacedysisException {
        ResourceValue value = ResourceValue.merge(resultFrame.getValue(slot), otherFrame.getValue(slot));
        resultFrame.setValue(slot, value);
    }

    @Override
    public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, ResourceValueFrame fact) throws DataflowreplacedysisException {
        visitor.setFrameAndLocation(fact, new Location(handle, basicBlock));
        visitor.transferInstruction(handle, basicBlock);
    }
}

19 View Complete Implementation : RepeatedConditionals.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
private boolean compareCode(int first, int endOfFirstSegment, int second, int endOfSecondSegment, boolean oppositeChecks) {
    if (endOfFirstSegment - first != endOfSecondSegment - second) {
        return false;
    }
    MethodGen methodGen = null;
    try {
        methodGen = Global.getreplacedysisCache().getMethodreplacedysis(MethodGen.clreplaced, getMethodDescriptor());
    } catch (CheckedreplacedysisException e) {
    // Ignore
    }
    if (methodGen == null) {
        // MethodGen is absent for some reason: fallback to byte-to-byte comparison
        byte[] code = getCode().getCode();
        for (int i = first; i < endOfFirstSegment; i++) {
            if (code[i] != code[i - first + second]) {
                return false;
            }
        }
        return true;
    }
    InstructionHandle firstHandle = methodGen.getInstructionList().findHandle(first);
    InstructionHandle secondHandle = methodGen.getInstructionList().findHandle(second);
    while (true) {
        if (firstHandle == null || secondHandle == null) {
            return false;
        }
        if (firstHandle.getPosition() >= endOfFirstSegment) {
            return secondHandle.getPosition() >= endOfSecondSegment;
        }
        if (secondHandle.getPosition() >= endOfSecondSegment) {
            return firstHandle.getPosition() >= endOfFirstSegment;
        }
        Instruction firstInstruction = firstHandle.getInstruction();
        Instruction secondInstruction = secondHandle.getInstruction();
        if (firstInstruction instanceof BranchInstruction && secondInstruction instanceof BranchInstruction) {
            int firstOpcode = firstInstruction.getOpcode();
            int secondOpcode = secondInstruction.getOpcode();
            if (firstOpcode != secondOpcode) {
                return false;
            }
            int firstTarget = ((BranchInstruction) firstInstruction).getTarget().getPosition();
            int secondTarget = ((BranchInstruction) secondInstruction).getTarget().getPosition();
            if (firstTarget == second) {
                if (oppositeChecks || secondTarget <= endOfSecondSegment) {
                    return false;
                }
            } else {
                if (!((firstTarget >= first && firstTarget <= endOfFirstSegment && firstTarget - first == secondTarget - second) || firstTarget == secondTarget)) {
                    return false;
                }
            }
        } else {
            if (!firstInstruction.equals(secondInstruction)) {
                return false;
            }
        }
        firstHandle = firstHandle.getNext();
        secondHandle = secondHandle.getNext();
    }
}

19 View Complete Implementation : StackFixer.java
Copyright MIT License
Author : contra
public void fixStack() {
    for (ClreplacedGen cg : cgs.values()) {
        for (Method method : cg.getMethods()) {
            MethodGen mg = new MethodGen(method, cg.getClreplacedName(), cg.getConstantPool());
            mg.removeNOPs();
            mg.setMaxLocals();
            mg.setMaxStack();
            cg.replaceMethod(method, mg.getMethod());
            logger.debug(String.format("Reset MaxStack and MaxLocals in %s.%s", cg.getClreplacedName(), mg.getName()));
        }
    }
}

19 View Complete Implementation : ExceptionHandlerMap.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
private void build(MethodGen methodGen) {
    CodeExceptionGen[] handlerList = methodGen.getExceptionHandlers();
    // Map handler start instructions to the actual exception handlers
    for (CodeExceptionGen exceptionHandler : handlerList) {
        addExceptionHandler(exceptionHandler);
    }
    // For each instruction, determine which handlers it can reach
    InstructionHandle handle = methodGen.getInstructionList().getStart();
    while (handle != null) {
        int offset = handle.getPosition();
        handlerLoop: for (CodeExceptionGen exceptionHandler : handlerList) {
            int startOfRange = exceptionHandler.getStartPC().getPosition();
            int endOfRange = exceptionHandler.getEndPC().getPosition();
            if (offset >= startOfRange && offset <= endOfRange) {
                // This handler is reachable from the instruction
                addHandler(handle, exceptionHandler);
                // If this handler handles all exception types
                // i.e., an ANY handler, or catch(Throwable...),
                // then no further (lower-priority)
                // handlers are reachable from the instruction.
                if (Hierarchy.isUniversalExceptionHandler(exceptionHandler.getCatchType())) {
                    break handlerLoop;
                }
            }
        }
        handle = handle.getNext();
    }
}

19 View Complete Implementation : TaintAnalysis.java
Copyright GNU Lesser General Public License v3.0
Author : find-sec-bugs
/**
 * Implements taint dataflow operations, in particular meeting facts, transfer
 * function is delegated to {@link TaintFrameModelingVisitor}
 *
 * @author David Formanek (Y Soft Corporation, a.s.)
 */
public clreplaced Taintreplacedysis extends FrameDataflowreplacedysis<Taint, TaintFrame> {

    private final MethodGen methodGen;

    private final MethodInfo methodDescriptor;

    private final TaintFrameModelingVisitor visitor;

    private int parameterStackSize;

    private List<Integer> slotToParameter;

    private static final List<String> TAINTED_ANNOTATIONS = loadFileContent("taint-config/taint-param-annotations.txt");

    /**
     * Constructs replacedysis for the given method
     *
     * @param methodGen method to replacedyze
     * @param dfs DFS algorithm
     * @param descriptor descriptor of the method to replacedyze
     * @param taintConfig configured and derived taint summaries
     */
    public Taintreplacedysis(MethodGen methodGen, DepthFirstSearch dfs, MethodDescriptor descriptor, TaintConfig taintConfig, List<TaintFrameAdditionalVisitor> visitors) {
        super(dfs);
        this.methodGen = methodGen;
        this.methodDescriptor = (MethodInfo) descriptor;
        this.visitor = new TaintFrameModelingVisitor(methodGen.getConstantPool(), descriptor, taintConfig, visitors, methodGen);
        computeParametersInfo(descriptor.getSignature(), descriptor.isStatic());
    }

    @Override
    protected void mergeValues(TaintFrame frame, TaintFrame result, int i) throws DataflowreplacedysisException {
        result.setValue(i, Taint.merge(result.getValue(i), frame.getValue(i)));
    }

    @Override
    public void transferInstruction(InstructionHandle handle, BasicBlock block, TaintFrame fact) throws DataflowreplacedysisException {
        visitor.setFrameAndLocation(fact, new Location(handle, block));
        visitor.replacedyzeInstruction(handle.getInstruction());
    }

    @Override
    public TaintFrame createFact() {
        return new TaintFrame(methodGen.getMaxLocals());
    }

    /**
     * Initialize the initial state of a TaintFrame.
     * @param fact Initial frame
     */
    @Override
    public void initEntryFact(TaintFrame fact) {
        fact.setValid();
        fact.clearStack();
        String methodFullSignature = methodDescriptor.getSlashedClreplacedName() + "." + methodDescriptor.getName() + methodDescriptor.getSignature();
        boolean inMainMethod = isInMainMethod();
        int numSlots = fact.getNumSlots();
        int numLocals = fact.getNumLocals();
        for (int i = 0; i < numSlots; ++i) {
            Taint value = new Taint(Taint.State.UNKNOWN);
            if (i < numLocals) {
                if (i < parameterStackSize) {
                    int stackOffset = parameterStackSize - i - 1;
                    if (isTaintedByAnnotation(i - 1)) {
                        value = new Taint(Taint.State.TAINTED);
                    // this would add line number for the first instruction in the method
                    // value.addLocation(new TaintLocation(methodDescriptor, 0,""), true);
                    } else if (inMainMethod) {
                        if (FindSecBugsGlobalConfig.getInstance().isTaintedMainArgument()) {
                            value = new Taint(Taint.State.TAINTED);
                        } else {
                            value = new Taint(Taint.State.SAFE);
                        }
                    } else {
                        value.addParameter(stackOffset);
                    }
                    value.addSource(new UnknownSource(UnknownSourceType.PARAMETER, value.getState()).setSignatureMethod(methodFullSignature).setParameterIndex(stackOffset));
                }
                value.setVariableIndex(i);
            }
            fact.setValue(i, value);
        }
    }

    /**
     * @return true if the method is the startup point of a console or gui application
     * ("public static void main(String[] args)"), false otherwise
     */
    private boolean isInMainMethod() {
        return methodDescriptor.isStatic() && "main".equals(methodDescriptor.getName()) && "([Ljava/lang/String;)V".equals(methodDescriptor.getSignature()) && methodGen.getMethod().isPublic();
    }

    /**
     * Determine if the slot value is tainted based on added framework annotations.
     * <hr/>
     * Example of mapping done:<br/>
     *
     * Method replacedyzed: "test(String,String,double)V"
     * For the slot no 2, it look at annotations on the parameter 2.
     * <pre>
     *          0               1               2               3
     *                                    +++++++++++++
     *  [ double param3 | double param3 | String param2 | String param1 ]
     * </pre>
     * <br/>
     * (Reminder : double and long take two slots for one parameter)
     *
     * @param slotNo
     * @return
     */
    private boolean isTaintedByAnnotation(int slotNo) {
        if (slotNo >= 0 && methodDescriptor.hasParameterAnnotations()) {
            int parameter = slotToParameter.get(slotNo);
            Collection<AnnotationValue> annotations = methodDescriptor.getParameterAnnotations(parameter);
            for (AnnotationValue annotation : annotations) {
                if (TAINTED_ANNOTATIONS.contains(annotation.getAnnotationClreplaced().getClreplacedName())) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void meetInto(TaintFrame fact, Edge edge, TaintFrame result) throws DataflowreplacedysisException {
        if (fact.isValid() && edge.isExceptionEdge()) {
            TaintFrame copy = null;
            // creates modifiable copy
            copy = modifyFrame(fact, copy);
            copy.clearStack();
            // do not trust values that are safe just when an exception occurs
            copy.pushValue(new Taint(Taint.State.UNKNOWN));
            fact = copy;
        }
        mergeInto(fact, result);
    }

    /**
     * This method must be called after executing the data flow
     */
    public void finishreplacedysis() {
        visitor.finishreplacedysis();
    }

    /**
     * Compute two values:
     *  <li>The number of values required on the stack for a specific call.</li>
     *  <li>The parameter replacedociation with each slot.</li>
     *
     * <hr/>
     *
     * For exemple : "(I[Ljava/lang/String;Ljava/lang/Object;)V" =>  void a(Integer, String, Object)<br/><br/>
     * Expected Stack prior the method invocation :<br/>
     * <pre>
     * +--------------+
     * | 0: Object    |
     * +--------------+
     * | 1: String    |
     * +--------------+
     * | 2: int       |
     * +--------------+
     * </pre>
     * <hr/>
     *
     * Special note: double and long (primitive types) value take two slots.<br/>
     * For exemple : "(IDJ)V" =>  void a(Integer, Double, Long)
     * <pre>
     * +--------------+
     * | 0: long  pt1 |
     * +--------------+
     * | 1: long  pt2 |
     * +--------------+
     * | 2: double pt1|
     * +--------------+
     * | 3: double pt2|
     * +--------------+
     * | 4: int       |
     * +--------------+
     * </pre>
     *
     * @param signature
     * @param isStatic
     * @return
     */
    private void computeParametersInfo(String signature, boolean isStatic) {
        replacedert signature != null && !signature.isEmpty();
        // static methods does not have reference to this
        int stackSize = isStatic ? 0 : 1;
        GenericSignatureParser parser = new GenericSignatureParser(signature);
        Iterator<String> iterator = parser.parameterSignatureIterator();
        int paramIdx = 0;
        slotToParameter = new ArrayList<Integer>();
        while (iterator.hasNext()) {
            String parameter = iterator.next();
            if (parameter.equals("D") || parameter.equals("J")) {
                // double and long types takes two slots
                stackSize += 2;
                slotToParameter.add(paramIdx);
                slotToParameter.add(paramIdx);
            } else {
                stackSize++;
                slotToParameter.add(paramIdx);
            }
            paramIdx++;
        }
        parameterStackSize = stackSize;
    }

    private static List<String> loadFileContent(String path) {
        try (InputStream in = Taintreplacedysis.clreplaced.getClreplacedLoader().getResourcereplacedtream(path);
            BufferedReader stream = new BufferedReader(new InputStreamReader(in, "utf-8"))) {
            String line;
            List<String> content = new ArrayList<String>();
            while ((line = stream.readLine()) != null) {
                content.add(line.trim());
            }
            return content;
        } catch (IOException ex) {
            replacedert false : ex.getMessage();
        }
        return new ArrayList<String>();
    }
}

19 View Complete Implementation : TestReturn03Creator.java
Copyright Apache License 2.0
Author : apache
private void createMethod_1() {
    final InstructionList il = new InstructionList();
    final MethodGen method = new MethodGen(Const.ACC_PUBLIC | Const.ACC_STATIC, Type.INT, Type.NO_ARGS, new String[] {}, "test3", TEST_PACKAGE + ".TestReturn03", il, _cp);
    final InstructionHandle ih_0 = il.append(InstructionConst.ACONST_NULL);
    // TODO why is this not used
    replacedert.replacedertNotNull(ih_0);
    il.append(InstructionFactory.createReturn(Type.OBJECT));
    method.setMaxStack();
    method.setMaxLocals();
    _cg.addMethod(method.getMethod());
    il.dispose();
}

19 View Complete Implementation : XFactory.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
public static XMethod createXMethod(MethodGen methodGen) {
    String clreplacedName = methodGen.getClreplacedName();
    String methodName = methodGen.getName();
    String methodSig = methodGen.getSignature();
    int accessFlags = methodGen.getAccessFlags();
    return createXMethod(clreplacedName, methodName, methodSig, accessFlags);
}

19 View Complete Implementation : ConstantPoolTestCase.java
Copyright Apache License 2.0
Author : apache
private InstructionHandle[] getInstructionHandles(final JavaClreplaced clazz, final ConstantPoolGen cp, final Method method) {
    final MethodGen methodGen = new MethodGen(method, clazz.getClreplacedName(), cp);
    final InstructionList instructionList = methodGen.getInstructionList();
    return instructionList.getInstructionHandles();
}

19 View Complete Implementation : JstlExpressionWhiteLister.java
Copyright GNU Lesser General Public License v3.0
Author : find-sec-bugs
@Override
public void visitField(FieldInstruction put, MethodGen methodGen, TaintFrame frameType, Taint taintFrame, int numProduced, ConstantPoolGen cpg) throws Exception {
}

19 View Complete Implementation : PerformanceTest.java
Copyright Apache License 2.0
Author : apache
private static void test(final File lib) throws IOException {
    final NanoTimer total = new NanoTimer();
    final NanoTimer parseTime = new NanoTimer();
    final NanoTimer cgenTime = new NanoTimer();
    final NanoTimer mgenTime = new NanoTimer();
    final NanoTimer mserTime = new NanoTimer();
    final NanoTimer serTime = new NanoTimer();
    System.out.println("parsing " + lib);
    total.start();
    try (JarFile jar = new JarFile(lib)) {
        final Enumeration<?> en = jar.entries();
        while (en.hasMoreElements()) {
            final JarEntry e = (JarEntry) en.nextElement();
            if (e.getName().endsWith(".clreplaced")) {
                byte[] bytes;
                try (InputStream in = jar.getInputStream(e)) {
                    bytes = read(in);
                }
                parseTime.start();
                final JavaClreplaced clazz = new ClreplacedParser(new ByteArrayInputStream(bytes), e.getName()).parse();
                parseTime.stop();
                cgenTime.start();
                final ClreplacedGen cg = new ClreplacedGen(clazz);
                cgenTime.stop();
                final Method[] methods = cg.getMethods();
                for (final Method m : methods) {
                    mgenTime.start();
                    final MethodGen mg = new MethodGen(m, cg.getClreplacedName(), cg.getConstantPool());
                    final InstructionList il = mg.getInstructionList();
                    mgenTime.stop();
                    mserTime.start();
                    if (il != null) {
                        mg.getInstructionList().setPositions();
                        mg.setMaxLocals();
                        mg.setMaxStack();
                    }
                    cg.replaceMethod(m, mg.getMethod());
                    mserTime.stop();
                }
                serTime.start();
                cg.getJavaClreplaced().getBytes();
                serTime.stop();
            }
        }
    }
    total.stop();
    if (REPORT) {
        System.out.println("ClreplacedParser.parse: " + parseTime);
        System.out.println("ClreplacedGen.init: " + cgenTime);
        System.out.println("MethodGen.init: " + mgenTime);
        System.out.println("MethodGen.getMethod: " + mserTime);
        System.out.println("ClreplacedGen.getJavaClreplaced.getBytes: " + serTime);
        System.out.println("Total: " + total);
        System.out.println();
    }
}

19 View Complete Implementation : ConstantAnalysis.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * Dataflow replacedysis to find constant values.
 *
 * @see edu.umd.cs.findbugs.ba.constant.Constant
 * @author David Hovemeyer
 */
public clreplaced Constantreplacedysis extends FrameDataflowreplacedysis<Constant, ConstantFrame> {

    private final MethodGen methodGen;

    private final ConstantFrameModelingVisitor visitor;

    public Constantreplacedysis(MethodGen methodGen, DepthFirstSearch dfs) {
        super(dfs);
        this.methodGen = methodGen;
        this.visitor = new ConstantFrameModelingVisitor(methodGen.getConstantPool());
    }

    @Override
    public ConstantFrame createFact() {
        return new ConstantFrame(methodGen.getMaxLocals());
    }

    @Override
    public void initEntryFact(ConstantFrame frame) {
        frame.setValid();
        frame.clearStack();
        int numSlots = frame.getNumSlots();
        for (int i = 0; i < numSlots; ++i) {
            frame.setValue(i, Constant.NOT_CONSTANT);
        }
    }

    @Override
    public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, ConstantFrame frame) throws DataflowreplacedysisException {
        visitor.setFrameAndLocation(frame, new Location(handle, basicBlock));
        visitor.replacedyzeInstruction(handle.getInstruction());
    }

    @Override
    public void meetInto(ConstantFrame fact, Edge edge, ConstantFrame result) throws DataflowreplacedysisException {
        if (fact.isValid()) {
            ConstantFrame tmpFact = null;
            if (edge.isExceptionEdge()) {
                tmpFact = modifyFrame(fact, null);
                tmpFact.clearStack();
                tmpFact.pushValue(Constant.NOT_CONSTANT);
            }
            if (tmpFact != null) {
                fact = tmpFact;
            }
        }
        mergeInto(fact, result);
    }

    @Override
    protected void mergeValues(ConstantFrame otherFrame, ConstantFrame resultFrame, int slot) throws DataflowreplacedysisException {
        Constant value = Constant.merge(resultFrame.getValue(slot), otherFrame.getValue(slot));
        resultFrame.setValue(slot, value);
    }
    // /*
    // * Test driver.
    // */
    // public static void main(String[] argv) throws Exception {
    // if (argv.length != 1) {
    // System.err.println("Usage: " + Constantreplacedysis.clreplaced.getName() +
    // " <clreplaced file>");
    // System.exit(1);
    // }
    // 
    // DataflowTestDriver<ConstantFrame, Constantreplacedysis> driver =
    // new DataflowTestDriver<ConstantFrame, Constantreplacedysis>() {
    // @Override
    // public Dataflow<ConstantFrame, Constantreplacedysis> createDataflow(
    // ClreplacedContext clreplacedContext,
    // Method method) throws CFGBuilderException, DataflowreplacedysisException {
    // return clreplacedContext.getConstantDataflow(method);
    // }
    // };
    // 
    // driver.execute(argv[0]);
    // }
}

19 View Complete Implementation : BetterCFGBuilder2.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * A CFGBuilder that really tries to construct accurate control flow graphs. The
 * CFGs it creates have accurate exception edges, and have accurately inlined
 * JSR subroutines.
 *
 * @author David Hovemeyer
 * @see CFG
 */
public clreplaced BetterCFGBuilder2 implements CFGBuilder, EdgeTypes, Debug {

    private static final boolean DEBUG = SystemProperties.getBoolean("cfgbuilder.debug");

    /*
     * ----------------------------------------------------------------------
     * Helper clreplacedes
     * ----------------------------------------------------------------------
     */
    /**
     * A work list item for creating the CFG for a subroutine.
     */
    private static clreplaced WorkLisreplacedem {

        private final InstructionHandle start;

        private final BasicBlock basicBlock;

        /**
         * Constructor.
         *
         * @param start
         *            first instruction in the basic block
         * @param basicBlock
         *            the basic block to build
         */
        public WorkLisreplacedem(InstructionHandle start, BasicBlock basicBlock) {
            this.start = start;
            this.basicBlock = basicBlock;
        }

        /**
         * Get the start instruction.
         */
        public InstructionHandle getStartInstruction() {
            return start;
        }

        /**
         * Get the basic block.
         */
        public BasicBlock getBasicBlock() {
            return basicBlock;
        }
    }

    /**
     * A placeholder for a control edge that escapes its subroutine to return
     * control back to an outer (calling) subroutine. It will turn into a real
     * edge during inlining.
     */
    private static clreplaced EscapeTarget {

        private final InstructionHandle target;

        @Edge.Type
        private final int edgeType;

        /**
         * Constructor.
         *
         * @param target
         *            the target instruction in a calling subroutine
         * @param edgeType
         *            the type of edge that should be created when the
         *            subroutine is inlined into its calling context
         */
        public EscapeTarget(InstructionHandle target, @Edge.Type int edgeType) {
            this.target = target;
            this.edgeType = edgeType;
        }

        /**
         * Get the target instruction.
         */
        public InstructionHandle getTarget() {
            return target;
        }

        /**
         * Get the edge type.
         */
        @Edge.Type
        public int getEdgeType() {
            return edgeType;
        }
    }

    /**
     * JSR subroutine. The top level subroutine is where execution starts. Each
     * subroutine has its own CFG. Eventually, all JSR subroutines will be
     * inlined into the top level subroutine, resulting in an accurate CFG for
     * the overall method.
     */
    private clreplaced Subroutine {

        private final InstructionHandle start;

        private final BitSet instructionSet;

        private final CFG cfgSub;

        private final IdenreplacedyHashMap<InstructionHandle, BasicBlock> blockMap;

        private final IdenreplacedyHashMap<BasicBlock, List<EscapeTarget>> escapeTargetListMap;

        private final BitSet returnBlockSet;

        private final BitSet exitBlockSet;

        private final BitSet unhandledExceptionBlockSet;

        private final LinkedList<WorkLisreplacedem> workList;

        /**
         * Constructor.
         *
         * @param start
         *            the start instruction for the subroutine
         */
        public Subroutine(InstructionHandle start) {
            this.start = start;
            this.instructionSet = new BitSet();
            this.cfgSub = new CFG();
            this.blockMap = new IdenreplacedyHashMap<>();
            this.escapeTargetListMap = new IdenreplacedyHashMap<>();
            this.returnBlockSet = new BitSet();
            this.exitBlockSet = new BitSet();
            this.unhandledExceptionBlockSet = new BitSet();
            this.workList = new LinkedList<>();
        }

        /**
         * Get the start instruction.
         */
        public InstructionHandle getStartInstruction() {
            return start;
        }

        /**
         * Allocate a new basic block in the subroutine.
         */
        public BasicBlock allocateBasicBlock() {
            return cfgSub.allocate();
        }

        /**
         * Add a work list item for a basic block to be constructed.
         */
        public void addItem(WorkLisreplacedem item) {
            workList.add(item);
        }

        /**
         * Are there more work list items?
         */
        public boolean hasMoreWork() {
            return !workList.isEmpty();
        }

        /**
         * Get the next work list item.
         */
        public WorkLisreplacedem nexreplacedem() {
            return workList.removeFirst();
        }

        /**
         * Get the entry block for the subroutine's CFG.
         */
        public BasicBlock getEntry() {
            return cfgSub.getEntry();
        }

        /**
         * Get the exit block for the subroutine's CFG.
         */
        public BasicBlock getExit() {
            return cfgSub.getExit();
        }

        /**
         * Get the start block for the subroutine's CFG. (I.e., the block
         * containing the start instruction.)
         */
        public BasicBlock getStartBlock() {
            return getBlock(start);
        }

        /**
         * Get the subroutine's CFG.
         */
        public CFG getCFG() {
            return cfgSub;
        }

        /**
         * Add an instruction to the subroutine. We keep track of which
         * instructions are part of which subroutines. No instruction may be
         * part of more than one subroutine.
         *
         * @param handle
         *            the instruction to be added to the subroutine
         */
        public void addInstruction(InstructionHandle handle) throws CFGBuilderException {
            int position = handle.getPosition();
            if (usedInstructionSet.get(position)) {
                throw new CFGBuilderException("Instruction " + handle + " visited in multiple subroutines");
            }
            instructionSet.set(position);
            usedInstructionSet.set(position);
        }

        /**
         * Is the given instruction part of this subroutine?
         */
        public boolean containsInstruction(InstructionHandle handle) {
            return instructionSet.get(handle.getPosition());
        }

        /**
         * Get the basic block in the subroutine for the given instruction. If
         * the block doesn't exist yet, it is created, and a work list item is
         * added which will populate it. Note that if start is an exception
         * thrower, the block returned will be its ETB.
         *
         * @param start
         *            the start instruction for the block
         * @return the basic block for the instruction
         */
        public BasicBlock getBlock(InstructionHandle start) {
            BasicBlock block = blockMap.get(start);
            if (block == null) {
                block = allocateBasicBlock();
                blockMap.put(start, block);
                // Block is an exception handler?
                CodeExceptionGen exceptionGen = exceptionHandlerMap.getHandlerForStartInstruction(start);
                if (exceptionGen != null) {
                    block.setExceptionGen(null, exceptionGen);
                }
                addItem(new WorkLisreplacedem(start, block));
            }
            return block;
        }

        /**
         * Indicate that the method returns at the end of the given block.
         *
         * @param block
         *            the returning block
         */
        public void setReturnBlock(BasicBlock block) {
            returnBlockSet.set(block.getLabel());
        }

        /**
         * Does the method return at the end of this block?
         */
        public boolean isReturnBlock(BasicBlock block) {
            return returnBlockSet.get(block.getLabel());
        }

        /**
         * Indicate that System.exit() is called at the end of the given block.
         *
         * @param block
         *            the exiting block
         */
        public void setExitBlock(BasicBlock block) {
            exitBlockSet.set(block.getLabel());
        }

        /**
         * Is System.exit() called at the end of this block?
         */
        public boolean isExitBlock(BasicBlock block) {
            return exitBlockSet.get(block.getLabel());
        }

        /**
         * Indicate that an unhandled exception may be thrown by the given
         * block.
         *
         * @param block
         *            the block throwing an unhandled exception
         */
        public void setUnhandledExceptionBlock(BasicBlock block) {
            unhandledExceptionBlockSet.set(block.getLabel());
        }

        /**
         * Does this block throw an unhandled exception?
         */
        public boolean isUnhandledExceptionBlock(BasicBlock block) {
            return unhandledExceptionBlockSet.get(block.getLabel());
        }

        /**
         * Add a control flow edge to the subroutine. If the control target has
         * not yet been added to the subroutine, a new work list item is added.
         * If the control target is in another subroutine, an EscapeTarget is
         * added.
         *
         * @param sourceBlock
         *            the source basic block
         * @param target
         *            the control target
         * @param edgeType
         *            the type of control edge
         */
        public void addEdgeAndExplore(BasicBlock sourceBlock, InstructionHandle target, @Edge.Type int edgeType) {
            if (usedInstructionSet.get(target.getPosition()) && !containsInstruction(target)) {
                // Control escapes this subroutine
                List<EscapeTarget> escapeTargetList = escapeTargetListMap.computeIfAbsent(sourceBlock, k -> new LinkedList<>());
                escapeTargetList.add(new EscapeTarget(target, edgeType));
            } else {
                // Edge within the current subroutine
                BasicBlock targetBlock = getBlock(target);
                addEdge(sourceBlock, targetBlock, edgeType);
            }
        }

        /**
         * Add an edge to the subroutine's CFG.
         *
         * @param sourceBlock
         *            the source basic block
         * @param destBlock
         *            the destination basic block
         * @param edgeType
         *            the type of edge
         */
        public void addEdge(BasicBlock sourceBlock, BasicBlock destBlock, @Edge.Type int edgeType) {
            if (VERIFY_INTEGRITY && destBlock.isExceptionHandler() && edgeType != HANDLED_EXCEPTION_EDGE) {
                throw new IllegalStateException("In method " + SignatureConverter.convertMethodSignature(methodGen) + ": exception handler " + destBlock.getFirstInstruction() + " reachable by non exception edge type " + edgeType);
            }
            cfgSub.createEdge(sourceBlock, destBlock, edgeType);
        }

        /**
         * Get an Iterator over the EscapeTargets of given basic block.
         *
         * @param sourceBlock
         *            the basic block
         * @return an Iterator over the EscapeTargets
         */
        public Iterator<EscapeTarget> escapeTargereplacederator(BasicBlock sourceBlock) {
            List<EscapeTarget> escapeTargetList = escapeTargetListMap.get(sourceBlock);
            if (escapeTargetList == null) {
                escapeTargetList = Collections.emptyList();
            }
            return escapeTargetList.iterator();
        }
    }

    /**
     * Inlining context. This essentially consists of a inlining site and a
     * subroutine to be inlined. A stack of calling contexts is maintained in
     * order to resolve EscapeTargets.
     */
    private static clreplaced Context {

        private final Context caller;

        private final Subroutine subroutine;

        private final CFG result;

        private final IdenreplacedyHashMap<BasicBlock, BasicBlock> blockMap;

        private final LinkedList<BasicBlock> workList;

        /**
         * Constructor.
         *
         * @param caller
         *            the calling context
         * @param subroutine
         *            the subroutine being inlined
         * @param result
         *            the result CFG
         */
        public Context(@Nullable Context caller, Subroutine subroutine, CFG result) {
            this.caller = caller;
            this.subroutine = subroutine;
            this.result = result;
            this.blockMap = new IdenreplacedyHashMap<>();
            this.workList = new LinkedList<>();
        }

        /**
         * Get the calling context.
         */
        public Context getCaller() {
            return caller;
        }

        /**
         * Get the subroutine being inlined.
         */
        public Subroutine getSubroutine() {
            return subroutine;
        }

        /**
         * Get the result CFG.
         */
        public CFG getResult() {
            return result;
        }

        /**
         * Add a basic block to the inlining work list.
         *
         *        public void addItem(BasicBlock item) {
         *            workList.add(item);
         *        }
         */
        /**
         * Are there more work list items?
         */
        public boolean hasMoreWork() {
            return !workList.isEmpty();
        }

        /**
         * Get the next work list item (basic block to be inlined).
         */
        public BasicBlock nexreplacedem() {
            return workList.removeFirst();
        }

        /**
         * Map a basic block in a subroutine to the corresponding block in the
         * resulting CFG.
         *
         * @param subBlock
         *            the subroutine block
         * @param resultBlock
         *            the result CFG block
         */
        public void mapBlock(BasicBlock subBlock, BasicBlock resultBlock) {
            blockMap.put(subBlock, resultBlock);
        }

        /**
         * Get the block in the result CFG corresponding to the given subroutine
         * block.
         *
         * @param subBlock
         *            the subroutine block
         * @return the result CFG block
         */
        public BasicBlock getBlock(BasicBlock subBlock) {
            BasicBlock resultBlock = blockMap.get(subBlock);
            if (resultBlock == null) {
                resultBlock = result.allocate();
                blockMap.put(subBlock, resultBlock);
                workList.add(subBlock);
            }
            return resultBlock;
        }

        /**
         * Check to ensure that this context is not the result of recursion.
         */
        public void checkForRecursion() throws CFGBuilderException {
            Context callerContext = caller;
            while (callerContext != null) {
                if (callerContext.subroutine == this.subroutine) {
                    throw new CFGBuilderException("JSR recursion detected!");
                }
                callerContext = callerContext.caller;
            }
        }
    }

    /*
     * ----------------------------------------------------------------------
     * Instance data
     * ----------------------------------------------------------------------
     */
    private final MethodGen methodGen;

    private final ConstantPoolGen cpg;

    private final ExceptionHandlerMap exceptionHandlerMap;

    private final BitSet usedInstructionSet;

    private final LinkedList<Subroutine> subroutineWorkList;

    private final IdenreplacedyHashMap<InstructionHandle, Subroutine> jsrSubroutineMap;

    private final Map<FieldDescriptor, Integer> addedFields = new HashMap<>();

    private Subroutine topLevelSubroutine;

    private CFG cfg;

    /*
     * ----------------------------------------------------------------------
     * Public methods
     * ----------------------------------------------------------------------
     */
    /**
     * Constructor.
     *
     * @param methodGen
     *            the method to build a CFG for
     */
    public BetterCFGBuilder2(@Nonnull MethodDescriptor descriptor, @Nonnull MethodGen methodGen) {
        this.methodGen = methodGen;
        this.cpg = methodGen.getConstantPool();
        IreplacedysisCache replacedysisCache = Global.getreplacedysisCache();
        StandardTypeMerger merger = null;
        ExceptionSetFactory exceptionSetFactory;
        try {
            exceptionSetFactory = replacedysisCache.getMethodreplacedysis(ExceptionSetFactory.clreplaced, descriptor);
            merger = new StandardTypeMerger(replacedysisContext.currentreplacedysisContext().getLookupFailureCallback(), exceptionSetFactory);
        } catch (CheckedreplacedysisException e) {
            replacedysisContext.logError("Unable to generate exceptionSetFactory for " + descriptor, e);
        }
        this.exceptionHandlerMap = new ExceptionHandlerMap(methodGen, merger);
        this.usedInstructionSet = new BitSet();
        this.jsrSubroutineMap = new IdenreplacedyHashMap<>();
        this.subroutineWorkList = new LinkedList<>();
    }

    public int getIndex(FieldDescriptor f) {
        Integer i = addedFields.get(f);
        if (i != null) {
            return i;
        }
        int index = cpg.addFieldref(f.getSlashedClreplacedName(), f.getName(), f.getSignature());
        addedFields.put(f, index);
        return index;
    }

    public void optimize(InstructionList instructionList) {
        InstructionHandle head = instructionList.getStart();
        while (head != null) {
            Instruction i = head.getInstruction();
            if (i instanceof INVOKESTATIC) {
                INVOKESTATIC is = (INVOKESTATIC) i;
                String name = is.getMethodName(cpg);
                String signature = is.getSignature(cpg);
                if (name.startsWith("access$")) {
                    XMethod invoked = XFactory.createXMethod(is, cpg);
                    FieldDescriptor field = invoked.getAccessMethodForField();
                    if (field != null) {
                        boolean isSetter = signature.endsWith("V");
                        Instruction replacement;
                        int index = getIndex(field);
                        if (field.isStatic()) {
                            if (isSetter) {
                                replacement = new PUTSTATIC(index);
                            } else {
                                replacement = new GETSTATIC(index);
                            }
                        } else {
                            if (isSetter) {
                                replacement = new PUTFIELD(index);
                            } else {
                                replacement = new GETFIELD(index);
                            }
                        }
                        head.swapInstruction(replacement);
                    /*
                            if (false)
                                System.out.println("Subsreplaceduting " + (isSetter ? "set" : "get") + " of " + field + " for call of "
                                    + invoked + " in " + methodGen.getClreplacedName() + "." + methodGen.getName()
                                    + methodGen.getSignature());
                         */
                    }
                }
            }
            if (i instanceof IfInstruction) {
                IfInstruction ii = (IfInstruction) i;
                InstructionHandle target = ii.getTarget();
                InstructionHandle next = head.getNext();
                if (target.equals(next)) {
                    int consumed = ii.consumeStack(methodGen.getConstantPool());
                    if (consumed != 1 && consumed != 2) {
                        throw new IllegalStateException();
                    }
                    head.swapInstruction(consumed == 1 ? new POP() : new POP2());
                }
            }
            if (i instanceof IFNULL || i instanceof IFNONNULL) {
                IfInstruction ii = (IfInstruction) i;
                InstructionHandle target = ii.getTarget();
                // ICONST
                InstructionHandle next1 = head.getNext();
                if (next1 == null) {
                    break;
                }
                if (next1.getInstruction() instanceof ICONST) {
                    // GOTO
                    InstructionHandle next2 = next1.getNext();
                    if (next2 == null) {
                        break;
                    }
                    // ICONST
                    InstructionHandle next3 = next2.getNext();
                    if (next3 == null) {
                        break;
                    }
                    InstructionHandle next4 = next3.getNext();
                    if (next4 == null) {
                        break;
                    }
                    if (target.equals(next3) && next2.getInstruction() instanceof GOTO && next3.getInstruction() instanceof ICONST && next1.getTargeters().length == 0 && next2.getTargeters().length == 0 && next3.getTargeters().length == 1 && next4.getTargeters().length == 1) {
                        int c1 = ((ICONST) next1.getInstruction()).getValue().intValue();
                        GOTO g = (GOTO) next2.getInstruction();
                        int c2 = ((ICONST) next3.getInstruction()).getValue().intValue();
                        if (g.getTarget().equals(next4) && (c1 == 1 && c2 == 0 || c1 == 0 && c2 == 1)) {
                            boolean nullIsTrue = i instanceof IFNULL && c2 == 1 || i instanceof IFNONNULL && c2 == 0;
                            if (nullIsTrue) {
                                // System.out.println("Found NULL2Z instruction");
                                head.swapInstruction(new NULL2Z());
                            } else {
                                // System.out.println("Found NONNULL2Z instruction");
                                head.swapInstruction(new NONNULL2Z());
                            }
                            next3.removeAllTargeters();
                            next4.removeAllTargeters();
                            next1.swapInstruction(new NOP());
                            next2.swapInstruction(new NOP());
                            next3.swapInstruction(new NOP());
                        }
                    }
                }
            }
            if (i instanceof ACONST_NULL) {
                InstructionHandle next = head.getNext();
                replacedert next != null;
                InstructionHandle next2 = next.getNext();
                if (next2 != null && next.getInstruction() instanceof ALOAD) {
                    Instruction check = next2.getInstruction();
                    if (check instanceof IF_ACMPNE || check instanceof IF_ACMPEQ) {
                        // need to update
                        head.swapInstruction(new NOP());
                        IfInstruction ifTest = (IfInstruction) check;
                        if (check instanceof IF_ACMPNE) {
                            next2.swapInstruction(new IFNONNULL(ifTest.getTarget()));
                        } else {
                            next2.swapInstruction(new IFNULL(ifTest.getTarget()));
                        }
                    }
                }
            }
            head = head.getNext();
        }
    }

    @Override
    public void build() throws CFGBuilderException {
        InstructionList instructionList = methodGen.getInstructionList();
        optimize(instructionList);
        topLevelSubroutine = new Subroutine(instructionList.getStart());
        subroutineWorkList.add(topLevelSubroutine);
        // Build top level subroutine and all JSR subroutines
        while (!subroutineWorkList.isEmpty()) {
            Subroutine subroutine = subroutineWorkList.removeFirst();
            if (DEBUG) {
                System.out.println("Starting subroutine " + subroutine.getStartInstruction());
            }
            build(subroutine);
        }
        // Inline everything into the top level subroutine
        cfg = inlineAll();
        // Add a NOP instruction to the entry block.
        // This allows replacedyses to construct a Location
        // representing the entry to the method.
        BasicBlock entryBlock = cfg.getEntry();
        InstructionList il = new InstructionList();
        entryBlock.addInstruction(il.append(new NOP()));
        cfg.checkIntegrity();
    }

    @Override
    public CFG getCFG() {
        return cfg;
    }

    /*
     * ----------------------------------------------------------------------
     * Implementation
     * ----------------------------------------------------------------------
     */
    /**
     * Build a subroutine. We iteratively add basic blocks to the subroutine
     * until there are no more blocks reachable from the calling context. As JSR
     * instructions are encountered, new Subroutines are added to the subroutine
     * work list.
     *
     * @param subroutine
     *            the subroutine
     */
    private void build(Subroutine subroutine) throws CFGBuilderException {
        // Prime the work list
        subroutine.addEdgeAndExplore(subroutine.getEntry(), subroutine.getStartInstruction(), START_EDGE);
        // Keep going until all basic blocks in the subroutine have been added
        while (subroutine.hasMoreWork()) {
            WorkLisreplacedem item = subroutine.nexreplacedem();
            InstructionHandle handle = item.getStartInstruction();
            BasicBlock basicBlock = item.getBasicBlock();
            // Add exception handler block (ETB) for exception-throwing
            // instructions
            if (isPEI(handle)) {
                if (DEBUG) {
                    System.out.println("ETB block " + basicBlock.getLabel() + " for " + handle);
                }
                handleExceptions(subroutine, handle, basicBlock);
                BasicBlock body = subroutine.allocateBasicBlock();
                subroutine.addEdge(basicBlock, body, FALL_THROUGH_EDGE);
                basicBlock = body;
            }
            if (DEBUG) {
                System.out.println("BODY block " + basicBlock.getLabel() + " for " + handle);
            }
            if (!basicBlock.isEmpty()) {
                throw new IllegalStateException("Block isn't empty!");
            }
            // Add instructions until we get to the end of the block
            boolean endOfBasicBlock = false;
            do {
                Instruction ins = handle.getInstruction();
                // Add the instruction to the block
                if (DEBUG) {
                    System.out.println("BB " + basicBlock.getLabel() + ": adding" + handle);
                }
                basicBlock.addInstruction(handle);
                subroutine.addInstruction(handle);
                short opcode = ins.getOpcode();
                // TODO: should check instruction to ensure that in a JSR
                // subroutine
                // no replacedignments are made to the local containing the return
                // address.
                // if (ins instanceof ASTORE) ...
                if (opcode == Const.JSR || opcode == Const.JSR_W) {
                    // Find JSR subroutine, add it to subroutine work list if
                    // we haven't built a CFG for it yet
                    JsrInstruction jsr = (JsrInstruction) ins;
                    InstructionHandle jsrTarget = jsr.getTarget();
                    Subroutine jsrSubroutine = jsrSubroutineMap.get(jsrTarget);
                    if (jsrSubroutine == null) {
                        jsrSubroutine = new Subroutine(jsrTarget);
                        jsrSubroutineMap.put(jsrTarget, jsrSubroutine);
                        subroutineWorkList.add(jsrSubroutine);
                    }
                    // This ends the basic block.
                    // Add a JSR_EDGE to the successor.
                    // It will be replaced later by the inlined JSR subroutine.
                    subroutine.addEdgeAndExplore(basicBlock, handle.getNext(), JSR_EDGE);
                    endOfBasicBlock = true;
                } else if (opcode == Const.RET) {
                    // End of JSR subroutine
                    subroutine.addEdge(basicBlock, subroutine.getExit(), RET_EDGE);
                    endOfBasicBlock = true;
                } else {
                    TargetEnumeratingVisitor visitor = new TargetEnumeratingVisitor(handle, cpg);
                    if (visitor.isEndOfBasicBlock()) {
                        endOfBasicBlock = true;
                        // Add control edges as appropriate
                        if (visitor.instructionIsThrow()) {
                            handleExceptions(subroutine, handle, basicBlock);
                        } else if (visitor.instructionIsExit()) {
                            subroutine.setExitBlock(basicBlock);
                        } else if (visitor.instructionIsReturn()) {
                            subroutine.setReturnBlock(basicBlock);
                        } else {
                            Iterator<Target> i = visitor.targereplacederator();
                            while (i.hasNext()) {
                                Target target = i.next();
                                subroutine.addEdgeAndExplore(basicBlock, target.getTargetInstruction(), target.getEdgeType());
                            }
                        }
                    }
                }
                if (!endOfBasicBlock) {
                    InstructionHandle next = handle.getNext();
                    if (next == null) {
                        throw new CFGBuilderException("Control falls off end of method: " + handle);
                    }
                    // Is the next instruction a control merge or a PEI?
                    if (isMerge(next) || isPEI(next)) {
                        subroutine.addEdgeAndExplore(basicBlock, next, FALL_THROUGH_EDGE);
                        endOfBasicBlock = true;
                    } else {
                        // Basic block continues
                        handle = next;
                    }
                }
            } while (!endOfBasicBlock);
        }
    }

    /**
     * Add exception edges for given instruction.
     *
     * @param subroutine
     *            the subroutine containing the instruction
     * @param pei
     *            the instruction which throws an exception
     * @param etb
     *            the exception thrower block (ETB) for the instruction
     */
    private void handleExceptions(Subroutine subroutine, InstructionHandle pei, BasicBlock etb) {
        etb.setExceptionThrower(pei);
        // Remember whether or not a universal exception handler
        // is reachable. If so, then we know that exceptions raised
        // at this instruction cannot propagate out of the method.
        boolean sawUniversalExceptionHandler = false;
        List<CodeExceptionGen> exceptionHandlerList = exceptionHandlerMap.getHandlerList(pei);
        if (exceptionHandlerList != null) {
            for (CodeExceptionGen exceptionHandler : exceptionHandlerList) {
                InstructionHandle handlerStart = exceptionHandler.getHandlerPC();
                subroutine.addEdgeAndExplore(etb, handlerStart, HANDLED_EXCEPTION_EDGE);
                if (Hierarchy.isUniversalExceptionHandler(exceptionHandler.getCatchType())) {
                    sawUniversalExceptionHandler = true;
                }
            }
        }
        // If required, mark this block as throwing an unhandled exception.
        // For now, we replacedume that if there is no reachable handler that handles
        // ANY exception type, then the exception can be thrown out of the
        // method.
        if (!sawUniversalExceptionHandler) {
            if (DEBUG) {
                System.out.println("Adding unhandled exception edge from " + pei);
            }
            subroutine.setUnhandledExceptionBlock(etb);
        }
    }

    /**
     * Return whether or not the given instruction can throw exceptions.
     *
     * @param handle
     *            the instruction
     * @return true if the instruction can throw an exception, false otherwise
     * @throws CFGBuilderException
     */
    private boolean isPEI(InstructionHandle handle) throws CFGBuilderException {
        Instruction ins = handle.getInstruction();
        if (!(ins instanceof ExceptionThrower)) {
            return false;
        }
        if (ins instanceof NEW) {
            return false;
        }
        // if (ins instanceof ATHROW) return false;
        if (ins instanceof GETSTATIC) {
            return false;
        }
        if (ins instanceof PUTSTATIC) {
            return false;
        }
        if (ins instanceof ReturnInstruction) {
            return false;
        }
        if (ins instanceof INSTANCEOF) {
            return false;
        }
        if (ins instanceof MONITOREXIT) {
            return false;
        }
        if (ins instanceof LDC) {
            return false;
        }
        if (ins instanceof GETFIELD && !methodGen.isStatic()) {
            // replacedume that GETFIELD on this object is not PEI
            return !isSafeFieldSource(handle.getPrev());
        }
        if (ins instanceof PUTFIELD && !methodGen.isStatic()) {
            // replacedume that PUTFIELD on this object is not PEI
            int depth = ins.consumeStack(cpg);
            for (InstructionHandle prev = handle.getPrev(); prev != null; prev = prev.getPrev()) {
                Instruction prevInst = prev.getInstruction();
                if (prevInst instanceof BranchInstruction) {
                    if (prevInst instanceof GotoInstruction) {
                        // Currently we support only jumps to the PUTFIELD itself
                        // This will cover simple cases like this.a = flag ? foo : bar
                        if (((BranchInstruction) prevInst).getTarget() == handle) {
                            depth = ins.consumeStack(cpg);
                        } else {
                            return true;
                        }
                    } else if (!(prevInst instanceof IfInstruction)) {
                        // As IF instructions may fall through then the stack depth remains unchanged
                        // Actually we should not go here for normal Java bytecode: switch or jsr should not appear in this context
                        return true;
                    }
                }
                depth = depth - prevInst.produceStack(cpg) + prevInst.consumeStack(cpg);
                if (depth < 1) {
                    throw new CFGBuilderException("Invalid stack at " + prev + " when checking " + handle);
                }
                if (depth == 1) {
                    InstructionHandle prevPrev = prev.getPrev();
                    if (prevPrev != null && prevPrev.getInstruction() instanceof BranchInstruction) {
                        continue;
                    }
                    return !isSafeFieldSource(prevPrev);
                }
            }
        }
        return true;
    }

    /**
     * @param handle instruction handle which loads the object for further GETFIELD/PUTFIELD operation
     * @return true if this object is known to be non-null
     */
    private boolean isSafeFieldSource(InstructionHandle handle) {
        while (handle != null && handle.getInstruction().getOpcode() == Const.DUP) {
            // Some compilers generate DUP for field increment code like
            // ALOAD_0 / DUP / GETFIELD x / ICONST_1 / IADD / PUTFIELD x
            handle = handle.getPrev();
        }
        if (handle == null) {
            return false;
        }
        Instruction inst = handle.getInstruction();
        if (inst.getOpcode() == Const.ALOAD_0) {
            return true;
        }
        return inst instanceof GETFIELD && ((GETFIELD) inst).getFieldName(cpg).startsWith("this$");
    }

    /**
     * Determine whether or not the given instruction is a control flow merge.
     *
     * @param handle
     *            the instruction
     * @return true if the instruction is a control merge, false otherwise
     */
    private static boolean isMerge(InstructionHandle handle) {
        if (handle.hasTargeters()) {
            // Check all targeters of this handle to see if any
            // of them are branches. If so, the instruction is a merge.
            InstructionTargeter[] targeterList = handle.getTargeters();
            for (InstructionTargeter targeter : targeterList) {
                if (targeter instanceof BranchInstruction) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Inline all JSR subroutines into the top-level subroutine. This produces a
     * complete CFG for the entire method, in which all JSR subroutines are
     * inlined.
     *
     * @return the CFG for the method
     */
    private CFG inlineAll() throws CFGBuilderException {
        CFG result = new CFG();
        Context rootContext = new Context(null, topLevelSubroutine, result);
        rootContext.mapBlock(topLevelSubroutine.getEntry(), result.getEntry());
        rootContext.mapBlock(topLevelSubroutine.getExit(), result.getExit());
        BasicBlock resultStartBlock = rootContext.getBlock(topLevelSubroutine.getStartBlock());
        result.createEdge(result.getEntry(), resultStartBlock, START_EDGE);
        inline(rootContext);
        return result;
    }

    /**
     * Inline a subroutine into a calling context.
     *
     * @param context
     *            the Context
     */
    public void inline(Context context) throws CFGBuilderException {
        CFG result = context.getResult();
        // Check to ensure we're not trying to inline something that is
        // recursive
        context.checkForRecursion();
        Subroutine subroutine = context.getSubroutine();
        CFG subCFG = subroutine.getCFG();
        while (context.hasMoreWork()) {
            BasicBlock subBlock = context.nexreplacedem();
            BasicBlock resultBlock = context.getBlock(subBlock);
            // Mark blocks which are in JSR subroutines
            resultBlock.setInJSRSubroutine(context.getCaller() != null);
            // Copy instructions into the result block
            BasicBlock.InstructionIterator insIter = subBlock.instructionIterator();
            while (insIter.hasNext()) {
                InstructionHandle handle = insIter.next();
                resultBlock.addInstruction(handle);
            }
            // Set exception thrower status
            if (subBlock.isExceptionThrower()) {
                resultBlock.setExceptionThrower(subBlock.getExceptionThrower());
            }
            // Set exception handler status
            if (subBlock.isExceptionHandler()) {
                resultBlock.setExceptionGen(null, subBlock.getExceptionGen());
            }
            // Add control edges (including inlining JSR subroutines)
            Iterator<Edge> edgeIter = subCFG.outgoingEdgeIterator(subBlock);
            while (edgeIter.hasNext()) {
                Edge edge = edgeIter.next();
                int edgeType = edge.getType();
                if (edgeType == JSR_EDGE) {
                    // Inline a JSR subroutine...
                    // Create a new Context
                    InstructionHandle jsrHandle = subBlock.getLastInstruction();
                    JsrInstruction jsr = (JsrInstruction) jsrHandle.getInstruction();
                    Subroutine jsrSub = jsrSubroutineMap.get(jsr.getTarget());
                    Context jsrContext = new Context(context, jsrSub, context.getResult());
                    // The start block in the JSR subroutine maps to the first
                    // inlined block in the result CFG.
                    BasicBlock resultJSRStartBlock = jsrContext.getBlock(jsrSub.getStartBlock());
                    result.createEdge(resultBlock, resultJSRStartBlock, GOTO_EDGE);
                    // The exit block in the JSR subroutine maps to the result
                    // block
                    // corresponding to the instruction following the JSR.
                    // (I.e., that is where control returns after the execution
                    // of
                    // the JSR subroutine.)
                    BasicBlock subJSRSuccessorBlock = subroutine.getBlock(jsrHandle.getNext());
                    BasicBlock resultJSRSuccessorBlock = context.getBlock(subJSRSuccessorBlock);
                    jsrContext.mapBlock(jsrSub.getExit(), resultJSRSuccessorBlock);
                    // Inline the JSR subroutine
                    inline(jsrContext);
                } else {
                    // Ordinary control edge
                    BasicBlock resultTarget = context.getBlock(edge.getTarget());
                    result.createEdge(resultBlock, resultTarget, edge.getType());
                }
            }
            // Add control edges for escape targets
            Iterator<EscapeTarget> escapeTargereplaceder = subroutine.escapeTargereplacederator(subBlock);
            while (escapeTargereplaceder.hasNext()) {
                EscapeTarget escapeTarget = escapeTargereplaceder.next();
                InstructionHandle targetInstruction = escapeTarget.getTarget();
                // Look for the calling context which has the target instruction
                Context caller = context.getCaller();
                while (caller != null) {
                    if (caller.getSubroutine().containsInstruction(targetInstruction)) {
                        break;
                    }
                    caller = caller.getCaller();
                }
                if (caller == null) {
                    throw new CFGBuilderException("Unknown caller for escape target " + targetInstruction + " referenced by " + context.getSubroutine().getStartInstruction());
                }
                // Find result block in caller
                BasicBlock subCallerTargetBlock = caller.getSubroutine().getBlock(targetInstruction);
                BasicBlock resultCallerTargetBlock = caller.getBlock(subCallerTargetBlock);
                // Add an edge to caller context
                result.createEdge(resultBlock, resultCallerTargetBlock, escapeTarget.getEdgeType());
            }
            // If the block returns from the method, add a return edge
            if (subroutine.isReturnBlock(subBlock)) {
                result.createEdge(resultBlock, result.getExit(), RETURN_EDGE);
            }
            // If the block calls System.exit(), add an exit edge
            if (subroutine.isExitBlock(subBlock)) {
                result.createEdge(resultBlock, result.getExit(), EXIT_EDGE);
            }
            // If the block throws an unhandled exception, add an unhandled
            // exception edge
            if (subroutine.isUnhandledExceptionBlock(subBlock)) {
                result.createEdge(resultBlock, result.getExit(), UNHANDLED_EXCEPTION_EDGE);
            }
        }
    /*
         * while (blocks are left) {
         *
         * get block from subroutine get corresponding block from result copy
         * instructions into result block
         *
         * if (block terminated by JSR) { get JSR subroutine create new context
         * create GOTO edge from current result block to start block of new
         * inlined context map subroutine exit block to result JSR successor
         * block inline (new context, result) } else { for each outgoing edge {
         * map each target to result blocks (add block to to work list if
         * needed) add edges to result }
         *
         * for each outgoing escape target { add edges into blocks in outer
         * contexts (adding those blocks to outer work list if needed) }
         *
         * if (block returns) { add return edge from result block to result CFG
         * exit block }
         *
         * if (block calls System.exit()) { add exit edge from result block to
         * result CFG exit block }
         *
         * if (block throws unhandled exception) { add unhandled exception edge
         * from result block to result CFG exit block } }
         *
         * }
         */
    }

    /**
     * Test driver.
     */
    public static void main(String[] argv) throws Exception {
        if (argv.length != 1) {
            System.err.println("Usage: " + BetterCFGBuilder2.clreplaced.getName() + " <clreplaced file>");
            System.exit(1);
        }
        String methodName = SystemProperties.getProperty("cfgbuilder.method");
        JavaClreplaced jclreplaced = new ClreplacedParser(argv[0]).parse();
        ClreplacedGen clreplacedGen = new ClreplacedGen(jclreplaced);
        Method[] methodList = jclreplaced.getMethods();
        for (Method method : methodList) {
            if (method.isAbstract() || method.isNative()) {
                continue;
            }
            if (methodName != null && !method.getName().equals(methodName)) {
                continue;
            }
            MethodDescriptor descriptor = DescriptorFactory.instance().getMethodDescriptor(jclreplaced, method);
            MethodGen methodGen = new MethodGen(method, jclreplaced.getClreplacedName(), clreplacedGen.getConstantPool());
            CFGBuilder cfgBuilder = new BetterCFGBuilder2(descriptor, methodGen);
            cfgBuilder.build();
            CFG cfg = cfgBuilder.getCFG();
            CFGPrinter cfgPrinter = new CFGPrinter(cfg);
            System.out.println("---------------------------------------------------------------------");
            System.out.println("Method: " + SignatureConverter.convertMethodSignature(methodGen));
            System.out.println("---------------------------------------------------------------------");
            cfgPrinter.print(System.out);
        }
    }
}

19 View Complete Implementation : PLSETestCase.java
Copyright Apache License 2.0
Author : apache
/**
 * BCEL-262:
 */
public void testB262() throws ClreplacedNotFoundException {
    final JavaClreplaced clazz = getTestClreplaced(PACKAGE_BASE_NAME + ".data.PLSETestEnum");
    final ClreplacedGen gen = new ClreplacedGen(clazz);
    final ConstantPoolGen pool = gen.getConstantPool();
    // get the values() method
    final Method m = gen.getMethodAt(0);
    final MethodGen mg = new MethodGen(m, gen.getClreplacedName(), pool);
    final InstructionList il = mg.getInstructionList();
    // get the invokevirtual instruction
    final InstructionHandle ih = il.findHandle(3);
    final InvokeInstruction ii = (InvokeInstruction) (ih.getInstruction());
    // without fix, the getClreplacedName() will throw:
    // java.lang.IllegalArgumentException: Cannot be used on an array type
    final String cn = ii.getClreplacedName(pool);
    replacedertEquals("[Lorg.apache.bcel.data.PLSETestEnum;", cn);
}

19 View Complete Implementation : LockAnalysis.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * replacedysis to determine where particular values are locked in a method. The
 * dataflow values are maps of value numbers to the number of times those values
 * are locked.
 *
 * @author David Hovemeyer
 * @see ValueNumberreplacedysis
 */
public clreplaced Lockreplacedysis extends ForwardDataflowreplacedysis<LockSet> {

    private static final boolean DEBUG = SystemProperties.getBoolean("la.debug");

    private final MethodGen methodGen;

    private final ValueNumberDataflow vnaDataflow;

    private final ValueNumberreplacedysis vna;

    private final boolean isSynchronized;

    private final boolean isStatic;

    public Lockreplacedysis(MethodGen methodGen, ValueNumberDataflow vnaDataflow, DepthFirstSearch dfs) {
        super(dfs);
        this.methodGen = methodGen;
        this.vnaDataflow = vnaDataflow;
        this.vna = vnaDataflow.getreplacedysis();
        this.isSynchronized = methodGen.isSynchronized();
        this.isStatic = methodGen.isStatic();
        if (DEBUG) {
            System.out.println("replacedyzing Locks in " + methodGen.getClreplacedName() + "." + methodGen.getName());
        }
    }

    @Override
    public LockSet createFact() {
        return new LockSet();
    }

    @Override
    public void copy(LockSet source, LockSet dest) {
        dest.copyFrom(source);
    }

    @Override
    public void initEntryFact(LockSet result) {
        result.clear();
        result.setDefaultLockCount(0);
        if (isSynchronized && !isStatic) {
            ValueNumber thisValue = vna.getThisValue();
            result.setLockCount(thisValue.getNumber(), 1);
        } else if (isSynchronized && isStatic) {
            ValueNumber thisValue = vna.getClreplacedObjectValue(methodGen.getClreplacedName());
            result.setLockCount(thisValue.getNumber(), 1);
        }
    }

    @Override
    public void makeFactTop(LockSet fact) {
        fact.clear();
        fact.setDefaultLockCount(LockSet.TOP);
    }

    @Override
    public boolean isTop(LockSet fact) {
        return fact.isTop();
    }

    @Override
    public boolean same(LockSet fact1, LockSet fact2) {
        return fact1.sameAs(fact2);
    }

    @Override
    public void meetInto(LockSet fact, Edge edge, LockSet result) throws DataflowreplacedysisException {
        result.meetWith(fact);
    }

    @Override
    public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, LockSet fact) throws DataflowreplacedysisException {
        Instruction ins = handle.getInstruction();
        short opcode = ins.getOpcode();
        if (opcode == Const.MONITORENTER || opcode == Const.MONITOREXIT) {
            ValueNumberFrame frame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock));
            modifyLock(frame, fact, opcode == Const.MONITORENTER ? 1 : -1);
        } else if (opcode == Const.INVOKEVIRTUAL || opcode == Const.INVOKEINTERFACE) {
            InvokeInstruction inv = (InvokeInstruction) ins;
            String name = inv.getMethodName(methodGen.getConstantPool());
            String sig = inv.getSignature(methodGen.getConstantPool());
            ValueNumberFrame frame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock));
            if ("()V".equals(sig) && ("lock".equals(name) || "lockInterruptibly".equals(name))) {
                modifyLock(frame, fact, 1);
            } else if ("()V".equals(sig) && ("unlock".equals(name))) {
                modifyLock(frame, fact, -1);
            }
        } else if ((ins instanceof ReturnInstruction) && isSynchronized && !isStatic) {
            lockOp(fact, vna.getThisValue().getNumber(), -1);
        }
    }

    private void modifyLock(ValueNumberFrame frame, LockSet fact, int delta) throws DataflowreplacedysisException {
        if (frame.isValid()) {
            int lockNumber = frame.getTopValue().getNumber();
            lockOp(fact, lockNumber, delta);
        }
    }

    private void lockOp(LockSet fact, int lockNumber, int delta) {
        int value = fact.getLockCount(lockNumber);
        if (value < 0) {
            return;
        }
        value += delta;
        if (value < 0) {
            value = LockSet.BOTTOM;
        }
        if (DEBUG) {
            System.out.println("Setting " + lockNumber + " to " + value + " in " + methodGen.getClreplacedName() + "." + methodGen.getName());
        }
        fact.setLockCount(lockNumber, value);
    }

    @Override
    public boolean isFactValid(LockSet fact) {
        return true;
    }
    // public static void main(String[] argv) throws Exception {
    // if (argv.length != 1) {
    // System.err.println("Usage: " + Lockreplacedysis.clreplaced.getName() +
    // " <clreplacedfile>");
    // System.exit(1);
    // }
    // 
    // DataflowTestDriver<LockSet, Lockreplacedysis> driver = new
    // DataflowTestDriver<LockSet, Lockreplacedysis>() {
    // @Override
    // public Dataflow<LockSet, Lockreplacedysis> createDataflow(ClreplacedContext
    // clreplacedContext, Method method)
    // throws CFGBuilderException, DataflowreplacedysisException {
    // return clreplacedContext.getLockDataflow(method);
    // }
    // };
    // 
    // driver.execute(argv[0]);
    // }
}

19 View Complete Implementation : Peephole.java
Copyright Apache License 2.0
Author : apache
public static void main(final String[] argv) {
    try {
        // Load the clreplaced from CLreplacedPATH.
        final JavaClreplaced clazz = Repository.lookupClreplaced(argv[0]);
        final Method[] methods = clazz.getMethods();
        final ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
        for (int i = 0; i < methods.length; i++) {
            if (!(methods[i].isAbstract() || methods[i].isNative())) {
                final MethodGen mg = new MethodGen(methods[i], clazz.getClreplacedName(), cp);
                final Method stripped = removeNOPs(mg);
                if (stripped != null) {
                    // Overwrite with stripped method
                    methods[i] = stripped;
                }
            }
        }
        // Dump the clreplaced to <clreplaced name>_.clreplaced
        clazz.setConstantPool(cp.getFinalConstantPool());
        clazz.dump(clazz.getClreplacedName() + "_.clreplaced");
    } catch (final Exception e) {
        e.printStackTrace();
    }
}

19 View Complete Implementation : ValueNumberAnalysis.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * <p>A dataflow replacedysis to track the production and flow of values in the Java
 * stack frame. See the {@link ValueNumber ValueNumber} clreplaced for an explanation
 * of what the value numbers mean, and when they can be compared.</p>
 *
 * <p>
 * This clreplaced is still experimental.</p>
 *
 * @author David Hovemeyer
 * @see ValueNumber
 * @see edu.umd.cs.findbugs.ba.Dominatorsreplacedysis
 */
public clreplaced ValueNumberreplacedysis extends FrameDataflowreplacedysis<ValueNumber, ValueNumberFrame> {

    private final static boolean TRACE = SystemProperties.getBoolean("vna.trace");

    public static final boolean DEBUG = TRACE || SystemProperties.getBoolean("vna.debug");

    private final MethodGen methodGen;

    private final ValueNumberFactory factory;

    private final ValueNumberFrameModelingVisitor visitor;

    private final ValueNumber[] entryLocalValueList;

    private final IdenreplacedyHashMap<BasicBlock, ValueNumber> exceptionHandlerValueNumberMap;

    private ValueNumber thisValue;

    private final HashMap<Location, ValueNumberFrame> factAtLocationMap;

    private final HashMap<Location, ValueNumberFrame> factAfterLocationMap;

    private MergeTree mergeTree;

    public ValueNumberreplacedysis(MethodGen methodGen, DepthFirstSearch dfs, LoadedFieldSet loadedFieldSet, RepositoryLookupFailureCallback lookupFailureCallback) {
        super(dfs);
        this.methodGen = methodGen;
        this.factory = new ValueNumberFactory();
        ValueNumberCache cache = new ValueNumberCache();
        this.visitor = new ValueNumberFrameModelingVisitor(methodGen, factory, cache, loadedFieldSet, lookupFailureCallback);
        int numLocals = methodGen.getMaxLocals();
        this.entryLocalValueList = new ValueNumber[numLocals];
        for (int i = 0; i < numLocals; ++i) {
            this.entryLocalValueList[i] = factory.createFreshValue();
        }
        this.exceptionHandlerValueNumberMap = new IdenreplacedyHashMap<>();
        // For non-static methods, keep track of which value represents the
        // "this" reference
        if (!methodGen.isStatic()) {
            this.thisValue = entryLocalValueList[0];
        }
        this.factAtLocationMap = new HashMap<>();
        this.factAfterLocationMap = new HashMap<>();
        if (DEBUG) {
            System.out.println("VNA replacedysis " + methodGen.getClreplacedName() + "." + methodGen.getName() + " : " + methodGen.getSignature());
        }
    }

    public ValueNumber getClreplacedObjectValue(String clreplacedName) {
        return visitor.factory.getClreplacedObjectValue(clreplacedName);
    }

    public void setMergeTree(MergeTree mergeTree) {
        this.mergeTree = mergeTree;
    }

    public MergeTree getMergeTree() {
        return mergeTree;
    }

    public ValueNumberFactory getFactory() {
        return factory;
    }

    public int getNumValuesAllocated() {
        return factory.getNumValuesAllocated();
    }

    public boolean isThisValue(ValueNumber value) {
        return thisValue != null && thisValue.getNumber() == value.getNumber();
    }

    public ValueNumber getThisValue() {
        return thisValue;
    }

    /**
     * Get the value number replacedigned to the given local variable upon entry to
     * the method.
     *
     * @param local
     *            local variable number
     * @return ValueNumber replacedigned to the local variable
     */
    public ValueNumber getEntryValue(int local) {
        return entryLocalValueList[local];
    }

    /**
     * Get the value number replacedigned to the given parameter upon entry to the
     * method.
     *
     * @param param
     *            a parameter (0 == first parameter)
     * @return the ValueNumber replacedigned to that parameter
     */
    public ValueNumber getEntryValueForParameter(int param) {
        SignatureParser sigParser = new SignatureParser(methodGen.getSignature());
        int p = 0;
        int slotOffset = methodGen.isStatic() ? 0 : 1;
        for (String paramSig : sigParser.parameterSignatures()) {
            if (p == param) {
                return getEntryValue(slotOffset);
            }
            p++;
            slotOffset += SignatureParser.getNumSlotsForType(paramSig);
        }
        throw new IllegalStateException();
    }

    @Override
    public ValueNumberFrame createFact() {
        return new ValueNumberFrame(methodGen.getMaxLocals());
    }

    @Override
    public void initEntryFact(ValueNumberFrame result) {
        // Change the frame from TOP to something valid.
        result.setValid();
        // At entry to the method, each local has (as far as we know) a unique
        // value.
        int numSlots = result.getNumSlots();
        for (int i = 0; i < numSlots; ++i) {
            result.setValue(i, entryLocalValueList[i]);
        }
    }

    @Override
    public void transfer(BasicBlock basicBlock, InstructionHandle end, ValueNumberFrame start, ValueNumberFrame result) throws DataflowreplacedysisException {
        if (basicBlock.isExceptionThrower() && isFactValid(start)) {
            /* If exceptionThrower is invoke instruction then it's possible that
             * it was partially executed before an exception occurred
             * So we have to kill available loads when control is transferred to the catch block
             */
            InstructionHandle handle = basicBlock.getExceptionThrower();
            Instruction inst = handle.getInstruction();
            if (inst instanceof InvokeInstruction || inst instanceof INVOKEDYNAMIC) {
                copy(start, result);
                visitor.setFrameAndLocation(result, new Location(handle, basicBlock));
                visitor.setHandle(handle);
                visitor.visitInvokeOnException(inst);
                return;
            }
        }
        super.transfer(basicBlock, end, start, result);
    }

    @Override
    public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, ValueNumberFrame fact) throws DataflowreplacedysisException {
        Location location = new Location(handle, basicBlock);
        ValueNumberFrame atLocation = getFactAtLocation(location);
        copy(fact, atLocation);
        visitor.setFrameAndLocation(fact, location);
        visitor.setHandle(handle);
        visitor.replacedyzeInstruction(handle.getInstruction());
        ValueNumberFrame afterLocation = getFactAfterLocation(location);
        copy(fact, afterLocation);
    }

    @Override
    public void meetInto(ValueNumberFrame fact, Edge edge, ValueNumberFrame result) throws DataflowreplacedysisException {
        if (edge.getTarget().isExceptionHandler() && fact.isValid()) {
            // Special case: when merging predecessor facts for entry to
            // an exception handler, we clear the stack and push a
            // single entry for the exception object. That way, the locals
            // can still be merged.
            // Get the value number for the exception
            BasicBlock handlerBlock = edge.getTarget();
            ValueNumber exceptionValueNumber = getExceptionValueNumber(handlerBlock);
            // Set up the stack frame
            ValueNumberFrame tmpFact = createFact();
            tmpFact.copyFrom(fact);
            tmpFact.clearStack();
            tmpFact.pushValue(exceptionValueNumber);
            fact = tmpFact;
        }
        mergeInto(fact, result);
    }

    @Override
    protected void mergeInto(ValueNumberFrame frame, ValueNumberFrame result) throws DataflowreplacedysisException {
        result.mergeAvailableLoadSets(frame, factory, mergeTree);
        super.mergeInto(frame, result);
    }

    @Override
    protected void mergeValues(ValueNumberFrame otherFrame, ValueNumberFrame resultFrame, int slot) throws DataflowreplacedysisException {
        ValueNumber value = mergeValues(resultFrame, slot, resultFrame.getValue(slot), otherFrame.getValue(slot));
        resultFrame.setValue(slot, value);
    }

    private ValueNumber mergeValues(ValueNumberFrame frame, int slot, ValueNumber mine, ValueNumber other) {
        // Merging slot values:
        // - Merging identical values results in no change
        // - If the values are different, and the value in the result
        // frame is not the result of a previous result, a fresh value
        // is allocated.
        // - If the value in the result frame is the result of a
        // previous merge, IT STAYS THE SAME.
        // 
        // The "one merge" rule means that merged values are essentially like
        // phi nodes. They combine some number of other values.
        // I believe (but haven't proved) that this technique is a dumb way
        // of computing SSA.
        if (mine != frame.getValue(slot)) {
            throw new IllegalStateException();
        }
        if (mine.equals(other)) {
            return mine;
        }
        ValueNumber mergedValue = frame.getMergedValue(slot);
        if (mergedValue == null) {
            mergedValue = factory.createFreshValue(ValueNumber.mergeFlags(mine.getFlags(), other.getFlags()) | ValueNumber.PHI_NODE);
            frame.setMergedValue(slot, mergedValue);
        }
        if (mergeTree != null) {
            mergeTree.mapInputToOutput(mine, mergedValue);
            mergeTree.mapInputToOutput(other, mergedValue);
        }
        return mergedValue;
    }

    @Override
    public ValueNumberFrame getFactAtLocation(Location location) {
        ValueNumberFrame fact = factAtLocationMap.get(location);
        if (fact == null) {
            fact = createFact();
            makeFactTop(fact);
            factAtLocationMap.put(location, fact);
        }
        return fact;
    }

    @Override
    public ValueNumberFrame getFactAfterLocation(Location location) {
        if (TRACE) {
            System.out.println("getting fact after " + location);
        }
        ValueNumberFrame fact = factAfterLocationMap.get(location);
        if (fact == null) {
            if (TRACE) {
                System.out.println("Initialized fact after " + location + " @ " + Integer.toHexString(System.idenreplacedyHashCode(location)) + " in " + Integer.toHexString(System.idenreplacedyHashCode(this)) + " : " + factAfterLocationMap.containsKey(location));
            }
            fact = createFact();
            makeFactTop(fact);
            factAfterLocationMap.put(location, fact);
        }
        return fact;
    }

    /**
     * Get an Iterator over all dataflow facts that we've recorded for the
     * Locations in the CFG. Note that this does not include result facts (since
     * there are no Locations corresponding to the end of basic blocks).
     */
    public Iterator<ValueNumberFrame> facreplacederator() {
        return factAtLocationMap.values().iterator();
    }

    // These fields are used by the compactValueNumbers() method.
    /*
    private static clreplaced ValueCompacter {
        public final BitSet valuesUsed;
    
        public int numValuesUsed;
    
        public final int[] discovered;
    
        public ValueCompacter(int origNumValuesAllocated) {
            valuesUsed = new BitSet();
            numValuesUsed = 0;
    
            // The "discovered" array tells us the mapping of old value numbers
            // to new (which are based on order of discovery). Negative values
            // specify value numbers which are not actually used (and thus can
            // be purged.)
            discovered = new int[origNumValuesAllocated];
            for (int i = 0; i < discovered.length; ++i) {
                discovered[i] = -1;
            }
        }
    
        public boolean isUsed(int number) {
            return valuesUsed.get(number);
        }
    
        public void setUsed(int number) {
            valuesUsed.set(number, true);
        }
    
        public int allocateValue() {
            return numValuesUsed++;
        }
    }
     */
    /**
     * <p>Compact the value numbers replacedigned. This should be done only after the
     * dataflow algorithm has executed. This works by modifying the actual
     * ValueNumber objects replacedigned. After this method is called, the
     * getNumValuesAllocated() method of this object will return a value less
     * than or equal to the value it would have returned before the call to this
     * method.
     * </p>
     * <p>
     * <em>This method should be called at most once</em>.
     * </p>
     * @param dataflow
     *            the Dataflow object which executed this replacedysis (and has all
     *            of the block result values)
     */
    @Deprecated
    public void compactValueNumbers(Dataflow<ValueNumberFrame, ValueNumberreplacedysis> dataflow) {
        throw new UnsupportedOperationException();
    }

    /**
     * Mark value numbers in a value number frame for compaction.
     *
     *    private static void markFrameValues(ValueNumberFrame frame, ValueCompacter compacter) {
     *        // We don't need to do anything for top and bottom frames.
     *        if (!frame.isValid()) {
     *            return;
     *        }
     *
     *        for (int j = 0; j < frame.getNumSlots(); ++j) {
     *            ValueNumber value = frame.getValue(j);
     *            int number = value.getNumber();
     *
     *            if (!compacter.isUsed(number)) {
     *                compacter.discovered[number] = compacter.allocateValue();
     *                compacter.setUsed(number);
     *            }
     *        }
     *    }
     */
    // /**
    // * Test driver.
    // */
    // public static void main(String[] argv) throws Exception {
    // 
    // if (argv.length != 1) {
    // System.out.println("Usage: edu.umd.cs.findbugs.ba.ValueNumberreplacedysis <filename>");
    // System.exit(1);
    // }
    // 
    // DataflowTestDriver<ValueNumberFrame, ValueNumberreplacedysis> driver =
    // new DataflowTestDriver<ValueNumberFrame, ValueNumberreplacedysis>() {
    // @Override
    // public Dataflow<ValueNumberFrame, ValueNumberreplacedysis>
    // createDataflow(ClreplacedContext clreplacedContext, Method method)
    // throws CFGBuilderException, DataflowreplacedysisException {
    // return clreplacedContext.getValueNumberDataflow(method);
    // }
    // };
    // 
    // driver.execute(argv[0]);
    // }
    private ValueNumber getExceptionValueNumber(BasicBlock handlerBlock) {
        ValueNumber valueNumber = exceptionHandlerValueNumberMap.get(handlerBlock);
        if (valueNumber == null) {
            valueNumber = factory.createFreshValue();
            exceptionHandlerValueNumberMap.put(handlerBlock, valueNumber);
        }
        return valueNumber;
    }

    @CheckForNull
    @DottedClreplacedName
    public String getClreplacedName(ValueNumber v) {
        return factory.getClreplacedName(v);
    }
}

19 View Complete Implementation : TaintDataflowEngine.java
Copyright GNU Lesser General Public License v3.0
Author : blackarbiter
private static String getSlashedMethodName(MethodGen methodGen) {
    String methodNameWithSignature = methodGen.getName() + methodGen.getSignature();
    String slashedClreplacedName = methodGen.getClreplacedName().replace('.', '/');
    return slashedClreplacedName + "." + methodNameWithSignature;
}

19 View Complete Implementation : MemberUtils.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * Checks if the method could be a lambda. Notice this is a best-check,
 * since once compiled lambda methods are not univocally distinguishable.
 *
 * @param m The method to check if it's a lambda
 * @return True if this could be a lambda, false otherwise
 */
public static boolean couldBeLambda(final MethodGen m) {
    return m.isPrivate() && internalIsSynthetic(m);
}

19 View Complete Implementation : ASTIfExpr.java
Copyright Apache License 2.0
Author : apache
/**
 * Fifth preplaced, produce Java byte code.
 */
@Override
public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
    if_expr.byte_code(il, method, cp);
    final InstructionList then_code = new InstructionList();
    final InstructionList else_code = new InstructionList();
    then_expr.byte_code(then_code, method, cp);
    else_expr.byte_code(else_code, method, cp);
    BranchHandle i, g;
    // If POP() == FALSE(i.e. 0) then branch to ELSE
    i = il.append(new IFEQ(null));
    ASTFunDecl.pop();
    il.append(then_code);
    g = il.append(new GOTO(null));
    i.setTarget(il.append(else_code));
    // May be optimized away later
    g.setTarget(il.append(InstructionConstants.NOP));
}

19 View Complete Implementation : JstlExpressionWhiteLister.java
Copyright GNU Lesser General Public License v3.0
Author : find-sec-bugs
@Override
public void visitLoad(LoadInstruction load, MethodGen methodGen, TaintFrame frameType, int numProduced, ConstantPoolGen cpg) {
}

19 View Complete Implementation : LocalVariableTypeTableTestCase.java
Copyright Apache License 2.0
Author : apache
public Method injection(final JavaClreplaced clazz, Method method, final ConstantPoolGen cp, final int firstStringOffset) {
    final MethodGen methodGen = new MethodGen(method, clazz.getClreplacedName(), cp);
    final InstructionList instructionList = methodGen.getInstructionList();
    instructionList.insert(instructionList.getStart(), makeWillBeAddedInstructionList(methodGen, firstStringOffset));
    methodGen.setMaxStack();
    methodGen.setMaxLocals();
    method = methodGen.getMethod();
    instructionList.dispose();
    return method;
}

19 View Complete Implementation : JstlExpressionWhiteLister.java
Copyright GNU Lesser General Public License v3.0
Author : find-sec-bugs
@Override
public void visitReturn(MethodGen methodGen, Taint returnValue, ConstantPoolGen cpg) throws Exception {
}

19 View Complete Implementation : helloify.java
Copyright Apache License 2.0
Author : apache
/**
 * Patch a method.
 */
private static Method helloifyMethod(Method m) {
    final Code code = m.getCode();
    final int flags = m.getAccessFlags();
    final String name = m.getName();
    // Sanity check
    if (m.isNative() || m.isAbstract() || (code == null)) {
        return m;
    }
    // Create instruction list to be inserted at method start.
    final String mesg = "Hello from " + Utility.methodSignatureToString(m.getSignature(), name, Utility.accessToString(flags));
    final InstructionList patch = new InstructionList();
    patch.append(new GETSTATIC(out));
    patch.append(new PUSH(cp, mesg));
    patch.append(new INVOKEVIRTUAL(println));
    final MethodGen mg = new MethodGen(m, clreplaced_name, cp);
    final InstructionList il = mg.getInstructionList();
    final InstructionHandle[] ihs = il.getInstructionHandles();
    if (name.equals("<init>")) {
        // First let the super or other constructor be called
        for (int j = 1; j < ihs.length; j++) {
            if (ihs[j].getInstruction() instanceof INVOKESPECIAL) {
                // Should check: method name == "<init>"
                il.append(ihs[j], patch);
                break;
            }
        }
    } else {
        il.insert(ihs[0], patch);
    }
    // Stack size must be at least 2, since the println method takes 2 argument.
    if (code.getMaxStack() < 2) {
        mg.setMaxStack(2);
    }
    m = mg.getMethod();
    // Reuse instruction handles
    il.dispose();
    return m;
}

19 View Complete Implementation : JPSXClassLoader.java
Copyright GNU General Public License v3.0
Author : kilograham
public static MethodGen emptyMethod(ClreplacedGen cgen, Method m) {
    MethodGen mg = new MethodGen(m, cgen.getClreplacedName(), cgen.getConstantPool());
    return new MethodGen(mg.getAccessFlags(), mg.getReturnType(), mg.getArgumentTypes(), mg.getArgumentNames(), mg.getName(), mg.getClreplacedName(), new InstructionList(), mg.getConstantPool());
}

19 View Complete Implementation : PLSETestCase.java
Copyright Apache License 2.0
Author : apache
/**
 * BCEL-295:
 */
public void testB295() throws Exception {
    final JavaClreplaced clazz = getTestClreplaced(PACKAGE_BASE_NAME + ".data.PLSETestClreplaced2");
    final ClreplacedGen cg = new ClreplacedGen(clazz);
    final ConstantPoolGen pool = cg.getConstantPool();
    // 'main'
    final Method m = cg.getMethodAt(1);
    final LocalVariableTable lvt = m.getLocalVariableTable();
    // 'i'
    final LocalVariable lv = lvt.getLocalVariable(2, 4);
    // System.out.println(lv);
    final MethodGen mg = new MethodGen(m, cg.getClreplacedName(), pool);
    final LocalVariableTable new_lvt = mg.getLocalVariableTable(mg.getConstantPool());
    // 'i'
    final LocalVariable new_lv = new_lvt.getLocalVariable(2, 4);
    // System.out.println(new_lv);
    replacedertEquals("live range length", lv.getLength(), new_lv.getLength());
}

19 View Complete Implementation : CFGBuilderFactory.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * Create a CFGBuilder to build a CFG for given method.
 *
 * @param methodGen
 *            the method
 * @return a CFGBuilder for the method
 */
public static CFGBuilder create(@Nonnull MethodDescriptor descriptor, @Nonnull MethodGen methodGen) {
    return new BetterCFGBuilder2(descriptor, methodGen);
}

19 View Complete Implementation : CFG.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
public void setMethodGen(MethodGen methodGen) {
    this.methodGen = methodGen;
}

19 View Complete Implementation : PLSETestCase.java
Copyright Apache License 2.0
Author : apache
/**
 * BCEL-79:
 */
public void testB79() throws ClreplacedNotFoundException {
    final JavaClreplaced clazz = getTestClreplaced(PACKAGE_BASE_NAME + ".data.PLSETestClreplaced");
    final ClreplacedGen gen = new ClreplacedGen(clazz);
    final ConstantPoolGen pool = gen.getConstantPool();
    final Method m = gen.getMethodAt(2);
    final LocalVariableTable lvt = m.getLocalVariableTable();
    // System.out.println(lvt);
    // System.out.println(lvt.getTableLength());
    final MethodGen mg = new MethodGen(m, gen.getClreplacedName(), pool);
    final LocalVariableTable new_lvt = mg.getLocalVariableTable(mg.getConstantPool());
    // System.out.println(new_lvt);
    replacedertEquals("number of locals", lvt.getTableLength(), new_lvt.getTableLength());
}

19 View Complete Implementation : Dataflow.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
private String getFullyQualifiedMethodName() {
    String methodName;
    MethodGen methodGen = cfg.getMethodGen();
    if (methodGen == null) {
        methodName = cfg.getMethodName();
    } else {
        methodName = SignatureConverter.convertMethodSignature(methodGen);
    }
    return methodName;
}

19 View Complete Implementation : Peephole.java
Copyright Apache License 2.0
Author : apache
private static Method removeNOPs(final MethodGen mg) {
    final InstructionList il = mg.getInstructionList();
    final InstructionFinder f = new InstructionFinder(il);
    // Find at least one NOP
    final String pat = "NOP+";
    InstructionHandle next = null;
    int count = 0;
    for (final Iterator<InstructionHandle[]> e = f.search(pat); e.hasNext(); ) {
        final InstructionHandle[] match = e.next();
        final InstructionHandle first = match[0];
        final InstructionHandle last = match[match.length - 1];
        // Some nasty Java compilers may add NOP at end of method.
        if ((next = last.getNext()) == null) {
            break;
        }
        count += match.length;
        // Delete NOPs and redirect any references to them to the following (non-nop) instruction.
        try {
            il.delete(first, last);
        } catch (final TargetLostException e2) {
            for (final InstructionHandle target : e2.getTargets()) {
                for (final InstructionTargeter targeter : target.getTargeters()) {
                    targeter.updateTarget(target, next);
                }
            }
        }
    }
    Method m = null;
    if (count > 0) {
        System.out.println("Removed " + count + " NOP instructions from method " + mg.getName());
        m = mg.getMethod();
    }
    // Reuse instruction handles
    il.dispose();
    return m;
}

19 View Complete Implementation : LineNumberMap.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * Summarize line numbers (and other source information) for a method.
 */
public clreplaced LineNumberMap {

    /**
     * Set this property to true to get debug print statements.
     */
    private static final boolean DEBUG = SystemProperties.getBoolean("lnm.debug");

    /**
     * When this is true, the workaround for the bug in BCEL 5.0's
     * LineNumberTable clreplaced is disabled.
     */
    private static final boolean LINE_NUMBER_BUG = SystemProperties.getBoolean("lineNumberBug");

    private final MethodGen methodGen;

    private final IdenreplacedyHashMap<InstructionHandle, LineNumber> lineNumberMap;

    private boolean hasLineNumbers;

    /**
     * Constructor.
     *
     * @param methodGen
     *            the method to summarize line numbers for
     */
    public LineNumberMap(MethodGen methodGen) {
        this.methodGen = methodGen;
        lineNumberMap = new IdenreplacedyHashMap<>();
        hasLineNumbers = false;
    }

    /**
     * Build the line number information. Should be called before any other
     * methods.
     */
    public void build() {
        int numGood = 0, numBytecodes = 0;
        if (DEBUG) {
            System.out.println("Method: " + methodGen.getName() + " - " + methodGen.getSignature() + "in clreplaced " + methodGen.getClreplacedName());
        }
        // replacedociate line number information with each InstructionHandle
        LineNumberTable table = methodGen.getLineNumberTable(methodGen.getConstantPool());
        if (table != null && table.getTableLength() > 0) {
            checkTable(table);
            InstructionHandle handle = methodGen.getInstructionList().getStart();
            while (handle != null) {
                int bytecodeOffset = handle.getPosition();
                if (bytecodeOffset < 0) {
                    throw new IllegalStateException("Bad bytecode offset: " + bytecodeOffset);
                }
                if (DEBUG) {
                    System.out.println("Looking for source line for bytecode offset " + bytecodeOffset);
                }
                int sourceLine;
                try {
                    sourceLine = table.getSourceLine(bytecodeOffset);
                } catch (ArrayIndexOutOfBoundsException e) {
                    if (LINE_NUMBER_BUG) {
                        throw e;
                    } else {
                        sourceLine = -1;
                    }
                }
                if (sourceLine >= 0) {
                    ++numGood;
                }
                lineNumberMap.put(handle, new LineNumber(bytecodeOffset, sourceLine));
                handle = handle.getNext();
                ++numBytecodes;
            }
            hasLineNumbers = true;
            if (DEBUG) {
                System.out.println("\t" + numGood + "/" + numBytecodes + " had valid line numbers");
            }
        }
    }

    private void checkTable(LineNumberTable table) {
        if (DEBUG) {
            System.out.println("line number table has length " + table.getTableLength());
        }
        LineNumber[] entries = table.getLineNumberTable();
        int lastBytecode = -1;
        for (int i = 0; i < entries.length; ++i) {
            LineNumber ln = entries[i];
            if (DEBUG) {
                System.out.println("Entry " + i + ": pc=" + ln.getStartPC() + ", line=" + ln.getLineNumber());
            }
            int pc = ln.getStartPC();
            if (pc <= lastBytecode) {
                throw new IllegalStateException("LineNumberTable is not sorted");
            }
        }
    }

    /**
     * Does this method have line number information?
     */
    public boolean hasLineNumbers() {
        return hasLineNumbers;
    }

    /**
     * Find the line number information for instruction whose handle is given.
     *
     * @param handle
     *            the InstructionHandle
     * @return the LineNumber object containing bytecode offset and source line
     *         number
     */
    public LineNumber lookupLineNumber(InstructionHandle handle) {
        return lineNumberMap.get(handle);
    }
}

19 View Complete Implementation : TestReturn01Creator.java
Copyright Apache License 2.0
Author : apache
private void createMethod_1() {
    final InstructionList il = new InstructionList();
    final MethodGen method = new MethodGen(Const.ACC_PUBLIC | Const.ACC_STATIC, Type.VOID, Type.NO_ARGS, new String[] {}, "foo", TEST_PACKAGE + ".TestReturn01", il, _cp);
    final InstructionHandle ih_0 = il.append(_factory.createNew("java.lang.Object"));
    // TODO why is this not used
    replacedert.replacedertNotNull(ih_0);
    il.append(InstructionConst.DUP);
    il.append(_factory.createInvoke("java.lang.Object", "<init>", Type.VOID, Type.NO_ARGS, Const.INVOKESPECIAL));
    il.append(InstructionConst.NOP);
    final InstructionHandle ih_8 = il.append(InstructionFactory.createReturn(Type.OBJECT));
    // TODO why is this not used
    replacedert.replacedertNotNull(ih_8);
    method.setMaxStack();
    method.setMaxLocals();
    _cg.addMethod(method.getMethod());
    il.dispose();
}

19 View Complete Implementation : PruneUnconditionalExceptionThrowerEdges.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
public clreplaced PruneUnconditionalExceptionThrowerEdges implements EdgeTypes {

    private static final boolean DEBUG = SystemProperties.getBoolean("cfg.prune.throwers.debug");

    private static final boolean DEBUG_DIFFERENCES = SystemProperties.getBoolean("cfg.prune.throwers.differences.debug");

    private static final String UNCONDITIONAL_THROWER_METHOD_NAMES = SystemProperties.getProperty("findbugs.unconditionalThrower", " ").replace(',', '|');

    private final MethodGen methodGen;

    private final CFG cfg;

    private final ConstantPoolGen cpg;

    private final TypeDataflow typeDataflow;

    private final replacedysisContext replacedysisContext;

    private boolean cfgModified;

    private static final Pattern unconditionalThrowerPattern;

    private static final BitSet RETURN_OPCODE_SET = new BitSet();

    static {
        RETURN_OPCODE_SET.set(Const.ARETURN);
        RETURN_OPCODE_SET.set(Const.IRETURN);
        RETURN_OPCODE_SET.set(Const.LRETURN);
        RETURN_OPCODE_SET.set(Const.DRETURN);
        RETURN_OPCODE_SET.set(Const.FRETURN);
        RETURN_OPCODE_SET.set(Const.RETURN);
        Pattern p;
        try {
            p = Pattern.compile(UNCONDITIONAL_THROWER_METHOD_NAMES);
            if (DEBUG) {
                System.out.println("Pattern is '" + p + "'");
                System.out.println(p.matcher("showInvalidPage").matches());
            }
        } catch (RuntimeException e) {
            replacedysisContext.logError("Error compiling unconditional thrower pattern " + UNCONDITIONAL_THROWER_METHOD_NAMES, e);
            p = Pattern.compile(" ");
        }
        unconditionalThrowerPattern = p;
    }

    public PruneUnconditionalExceptionThrowerEdges(/* ClreplacedContext clreplacedContext, */
    JavaClreplaced javaClreplaced, Method method, MethodGen methodGen, CFG cfg, ConstantPoolGen cpg, TypeDataflow typeDataflow, replacedysisContext replacedysisContext) {
        // this.clreplacedContext = clreplacedContext;
        this.methodGen = methodGen;
        this.cfg = cfg;
        this.cpg = cpg;
        this.typeDataflow = typeDataflow;
        this.replacedysisContext = replacedysisContext;
    }

    public void execute() throws DataflowreplacedysisException {
        replacedysisContext currentreplacedysisContext = replacedysisContext.currentreplacedysisContext();
        if (currentreplacedysisContext.getBoolProperty(replacedysisFeatures.CONSERVE_SPACE)) {
            throw new IllegalStateException("This should not happen");
        }
        boolean foundInexact = false;
        Set<Edge> deletedEdgeSet = new HashSet<>();
        // TypeDataflow typeDataflow = clreplacedContext.getTypeDataflow(method);
        if (DEBUG) {
            System.out.println("PruneUnconditionalExceptionThrowerEdges: examining " + SignatureConverter.convertMethodSignature(methodGen));
        }
        for (Iterator<BasicBlock> i = cfg.blockIterator(); i.hasNext(); ) {
            BasicBlock basicBlock = i.next();
            if (!basicBlock.isExceptionThrower()) {
                continue;
            }
            InstructionHandle instructionHandle = basicBlock.getExceptionThrower();
            Instruction exceptionThrower = instructionHandle.getInstruction();
            if (!(exceptionThrower instanceof InvokeInstruction)) {
                continue;
            }
            if (exceptionThrower instanceof INVOKEDYNAMIC) {
                continue;
            }
            InvokeInstruction inv = (InvokeInstruction) exceptionThrower;
            boolean foundThrower = false;
            boolean foundNonThrower = false;
            boolean isExact = true;
            XMethod primaryXMethod = XFactory.createXMethod(inv, cpg);
            final String methodName = primaryXMethod.getName();
            final boolean matches = unconditionalThrowerPattern.matcher(methodName).matches();
            if (DEBUG) {
                System.out.println("Checking '" + methodName + "' is " + matches);
            }
            if (matches) {
                if (DEBUG) {
                    System.out.println("\tmatched for " + instructionHandle + " : " + primaryXMethod);
                }
                foundThrower = true;
            } else if (inv instanceof INVOKEINTERFACE) {
                continue;
            } else if (inv instanceof INVOKESTATIC) {
                foundThrower = isUnconditionalThrower(primaryXMethod);
            } else {
                String clreplacedName = inv.getClreplacedName(cpg);
                if (DEBUG) {
                    System.out.println("\tlooking up method for " + instructionHandle + " : " + primaryXMethod);
                }
                Location loc = new Location(instructionHandle, basicBlock);
                TypeFrame typeFrame = typeDataflow.getFactAtLocation(loc);
                // if (primaryXMethod.isAbstract()) continue;
                Set<XMethod> targetSet = null;
                try {
                    if (clreplacedName.startsWith("[")) {
                        continue;
                    }
                    String methodSig = inv.getSignature(cpg);
                    if (!methodSig.endsWith("V") && !methodSig.endsWith("Exception;") && !methodSig.endsWith("Error;") && !methodSig.endsWith(")Ljava/lang/Object;")) {
                        continue;
                    }
                    targetSet = Hierarchy2.resolveMethodCallTargets(inv, typeFrame, cpg);
                    for (XMethod xMethod : targetSet) {
                        if (DEBUG) {
                            System.out.println("\tFound " + xMethod);
                        }
                        // Ignore abstract and native methods
                        boolean isUnconditionalThrower = isUnconditionalThrower(xMethod);
                        if (isUnconditionalThrower) {
                            if (!(xMethod.isFinal() || xMethod.isStatic() || xMethod.isPrivate())) {
                                try {
                                    isExact = false;
                                    XClreplaced xClreplaced = Global.getreplacedysisCache().getClreplacedreplacedysis(XClreplaced.clreplaced, xMethod.getClreplacedDescriptor());
                                    if (xClreplaced.isAbstract()) {
                                        continue;
                                    }
                                } catch (CheckedreplacedysisException e) {
                                    replacedysisContext.logError("Unable to resolve clreplaced for " + xMethod, e);
                                }
                            }
                            foundThrower = true;
                            if (DEBUG) {
                                System.out.println("Found thrower");
                            }
                        } else {
                            foundNonThrower = true;
                            if (DEBUG) {
                                System.out.println("Found non thrower");
                            }
                        }
                    }
                } catch (ClreplacedNotFoundException e) {
                    replacedysisContext.getLookupFailureCallback().reportMissingClreplaced(e);
                }
            }
            boolean newResult = foundThrower && !foundNonThrower;
            if (newResult) {
                if (!isExact) {
                    foundInexact = true;
                }
                // Method always throws an unhandled exception
                // Remove the normal control flow edge from the CFG.
                Edge fallThrough = cfg.getOutgoingEdgeWithType(basicBlock, FALL_THROUGH_EDGE);
                if (fallThrough != null) {
                    if (DEBUG) {
                        System.out.println("\tREMOVING normal return for: " + primaryXMethod);
                    }
                    deletedEdgeSet.add(fallThrough);
                }
            }
        }
        if (!deletedEdgeSet.isEmpty()) {
            cfgModified = true;
            if (foundInexact) {
                cfg.setFlag(CFG.FOUND_INEXACT_UNCONDITIONAL_THROWERS);
            }
            // Remove all edges marked for deletion
            for (Edge edge : deletedEdgeSet) {
                cfg.removeEdge(edge);
            }
        }
    }

    private boolean isUnconditionalThrower(XMethod xMethod) {
        return xMethod.isUnconditionalThrower() && !xMethod.isUnsupported() && !xMethod.isSynthetic();
    }

    /**
     * @param xMethod
     * @param javaClreplaced
     * @param method
     * @return true if method unconditionally throws
     * @deprecated Use {@link #doesMethodUnconditionallyThrowException(XMethod)}
     *             instead
     */
    @Deprecated
    static public Boolean doesMethodUnconditionallyThrowException(XMethod xMethod, JavaClreplaced javaClreplaced, Method method) {
        return doesMethodUnconditionallyThrowException(xMethod);
    }

    /**
     * @param xMethod
     * @return true if method unconditionally throws
     */
    static public boolean doesMethodUnconditionallyThrowException(XMethod xMethod) {
        return xMethod.isUnconditionalThrower();
    }

    /**
     * Return whether or not the CFG was modified.
     *
     * @return true if CFG was modified, false otherwise
     */
    public boolean wasCFGModified() {
        return cfgModified;
    }
}

19 View Complete Implementation : ASTFunAppl.java
Copyright Apache License 2.0
Author : apache
/**
 * Fifth preplaced, produce Java byte code.
 */
@Override
public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
    final String fname = name.getName();
    // Function   f     = function;
    // ASTIdent   fun   = f.getName();
    // ASTIdent[] args  = f.getArgs();
    final String clreplaced_name = method.getClreplacedName();
    if (fname.equals("READ")) {
        il.append(new INVOKESTATIC(cp.addMethodref(clreplaced_name, "_readInt", "()I")));
    } else if (fname.equals("WRITE")) {
        exprs[0].byte_code(il, method, cp);
        ASTFunDecl.pop();
        il.append(new INVOKESTATIC(cp.addMethodref(clreplaced_name, "_writeInt", "(I)I")));
    } else {
        // Normal function
        final int size = exprs.length;
        Type[] argv = null;
        if (exprs != null) {
            argv = new Type[size];
            for (int i = 0; i < size; i++) {
                argv[i] = Type.INT;
                exprs[i].byte_code(il, method, cp);
            }
        // ASTFunDecl.push(size);
        }
        ASTFunDecl.pop(size);
        // Function call
        il.append(new INVOKESTATIC(cp.addMethodref(clreplaced_name, fname, Type.getMethodSignature(Type.INT, argv))));
    }
    ASTFunDecl.push();
}

19 View Complete Implementation : SignatureConverter.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * Convenience method for generating a method signature in human readable
 * form.
 *
 * @param methodGen
 *            the method to produce a method signature for
 */
public static String convertMethodSignature(MethodGen methodGen) {
    return convertMethodSignature(methodGen.getClreplacedName(), methodGen.getName(), methodGen.getSignature());
}

19 View Complete Implementation : TaintAnalysis.java
Copyright GNU Lesser General Public License v3.0
Author : blackarbiter
/**
 * Implements taint dataflow operations, in particular meeting facts, transfer
 * function is delegated to {@link TaintFrameModelingVisitor}
 *
 * @author David Formanek (Y Soft Corporation, a.s.)
 */
public clreplaced Taintreplacedysis extends FrameDataflowreplacedysis<Taint, TaintFrame> {

    private final MethodGen methodGen;

    private final MethodInfo methodDescriptor;

    private final TaintFrameModelingVisitor visitor;

    private int parameterStackSize;

    private List<Integer> slotToParameter;

    private static final List<String> TAINTED_ANNOTATIONS = loadFileContent("taint-config/taint-param-annotations.txt");

    /**
     * Constructs replacedysis for the given method
     *
     * @param methodGen method to replacedyze
     * @param dfs DFS algorithm
     * @param descriptor descriptor of the method to replacedyze
     * @param taintConfig configured and derived taint summaries
     */
    public Taintreplacedysis(MethodGen methodGen, DepthFirstSearch dfs, MethodDescriptor descriptor, TaintConfig taintConfig) {
        super(dfs);
        this.methodGen = methodGen;
        this.methodDescriptor = (MethodInfo) descriptor;
        this.visitor = new TaintFrameModelingVisitor(methodGen.getConstantPool(), descriptor, taintConfig);
        computeParametersInfo(descriptor.getSignature(), descriptor.isStatic());
    }

    @Override
    protected void mergeValues(TaintFrame frame, TaintFrame result, int i) throws DataflowreplacedysisException {
        result.setValue(i, Taint.merge(result.getValue(i), frame.getValue(i)));
    }

    @Override
    public void transferInstruction(InstructionHandle handle, BasicBlock block, TaintFrame fact) throws DataflowreplacedysisException {
        visitor.setFrameAndLocation(fact, new Location(handle, block));
        visitor.replacedyzeInstruction(handle.getInstruction());
    }

    @Override
    public TaintFrame createFact() {
        return new TaintFrame(methodGen.getMaxLocals());
    }

    /**
     * Initialize the initial state of a TaintFrame.
     * @param fact Initial frame
     */
    @Override
    public void initEntryFact(TaintFrame fact) {
        fact.setValid();
        fact.clearStack();
        boolean inMainMethod = isInMainMethod();
        int numSlots = fact.getNumSlots();
        int numLocals = fact.getNumLocals();
        for (int i = 0; i < numSlots; ++i) {
            Taint value = new Taint(Taint.State.UNKNOWN);
            if (i < numLocals) {
                if (i < parameterStackSize) {
                    if (isTaintedByAnnotation(i - 1)) {
                        value = new Taint(Taint.State.TAINTED);
                    // this would add line number for the first instruction in the method
                    // value.addLocation(new TaintLocation(methodDescriptor, 0), true);
                    } else if (inMainMethod) {
                        if (FindSecBugsGlobalConfig.getInstance().isTaintedMainArgument()) {
                            value = new Taint(Taint.State.TAINTED);
                        } else {
                            value = new Taint(Taint.State.SAFE);
                        }
                    } else {
                        int stackOffset = parameterStackSize - i - 1;
                        value.addParameter(stackOffset);
                    }
                }
                value.setVariableIndex(i);
            }
            fact.setValue(i, value);
        }
    }

    /**
     * @return true if the method is the startup point of a console or gui application
     * ("public static void main(String[] args)"), false otherwise
     */
    private boolean isInMainMethod() {
        return methodDescriptor.isStatic() && "main".equals(methodDescriptor.getName()) && "([Ljava/lang/String;)V".equals(methodDescriptor.getSignature()) && methodGen.getMethod().isPublic();
    }

    /**
     * 添加注解是否被污染
     *  Determine if the slot value is tainted based on added framework annotations.
     *  <hr/>
     *  Example of mapping done:<br/>
     *
     *  Method replacedyzed: "test(String,String,double)V"
     *  For the slot no 2, it look at annotations on the parameter 2.
     *  <pre>
     *           0               1               2               3
     *                                     +++++++++++++
     *   [ double param3 | double param3 | String param2 | String param1 ]
     *  </pre>
     *  <br/>
     *  (Reminder : double and long take two slots for one parameter)
     *
     *  @param slotNo
     *  @return
     */
    private boolean isTaintedByAnnotation(int slotNo) {
        if (slotNo >= 0 && methodDescriptor.hasParameterAnnotations()) {
            int parameter = slotToParameter.get(slotNo);
            Collection<AnnotationValue> annotations = methodDescriptor.getParameterAnnotations(parameter);
            for (AnnotationValue annotation : annotations) {
                if (TAINTED_ANNOTATIONS.contains(annotation.getAnnotationClreplaced().getClreplacedName())) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public void meetInto(TaintFrame fact, Edge edge, TaintFrame result) throws DataflowreplacedysisException {
        if (fact.isValid() && edge.isExceptionEdge()) {
            TaintFrame copy = null;
            // creates modifiable copy
            copy = modifyFrame(fact, copy);
            copy.clearStack();
            // do not trust values that are safe just when an exception occurs
            copy.pushValue(new Taint(Taint.State.UNKNOWN));
            fact = copy;
        }
        mergeInto(fact, result);
    }

    /**
     * This method must be called after executing the data flow
     */
    public void finishreplacedysis() {
        visitor.finishreplacedysis();
    }

    /**
     * Compute two values:
     *  <li>The number of values required on the stack for a specific call.</li>
     *  <li>The parameter replacedociation with each slot.</li>
     *
     * <hr/>
     *
     * For exemple : "(I[Ljava/lang/String;Ljava/lang/Object;)V" =>  void a(Integer, String, Object)<br/><br/>
     * Expected Stack prior the method invocation :<br/>
     * <pre>
     * +--------------+
     * | 0: Object    |
     * +--------------+
     * | 1: String    |
     * +--------------+
     * | 2: int       |
     * +--------------+
     * </pre>
     * <hr/>
     *
     * Special note: double and long (primitive types) value take two slots.<br/>
     * For exemple : "(IDJ)V" =>  void a(Integer, Double, Long)
     * <pre>
     * +--------------+
     * | 0: long  pt1 |
     * +--------------+
     * | 1: long  pt2 |
     * +--------------+
     * | 2: double pt1|
     * +--------------+
     * | 3: double pt2|
     * +--------------+
     * | 4: int       |
     * +--------------+
     * </pre>
     *
     * @param signature
     * @param isStatic
     * @return
     */
    private void computeParametersInfo(String signature, boolean isStatic) {
        replacedert signature != null && !signature.isEmpty();
        // static methods does not have reference to this
        int stackSize = isStatic ? 0 : 1;
        GenericSignatureParser parser = new GenericSignatureParser(signature);
        Iterator<String> iterator = parser.parameterSignatureIterator();
        int paramIdx = 0;
        slotToParameter = new ArrayList<Integer>();
        while (iterator.hasNext()) {
            String parameter = iterator.next();
            if (parameter.equals("D") || parameter.equals("J")) {
                // double and long types takes two slots
                stackSize += 2;
                slotToParameter.add(paramIdx);
                slotToParameter.add(paramIdx);
            } else {
                stackSize++;
                slotToParameter.add(paramIdx);
            }
            paramIdx++;
        }
        parameterStackSize = stackSize;
    }

    private static List<String> loadFileContent(String path) {
        BufferedReader stream = null;
        try {
            InputStream in = Taintreplacedysis.clreplaced.getClreplacedLoader().getResourcereplacedtream(path);
            stream = new BufferedReader(new InputStreamReader(in, "utf-8"));
            String line;
            List<String> content = new ArrayList<String>();
            while ((line = stream.readLine()) != null) {
                content.add(line.trim());
            }
            return content;
        } catch (IOException ex) {
            replacedert false : ex.getMessage();
        } finally {
            IO.close(stream);
        }
        return new ArrayList<String>();
    }
}

19 View Complete Implementation : ValueNumberFrameModelingVisitor.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * Visitor which models the effects of bytecode instructions on value numbers of
 * values in the operand stack frames.
 *
 * @see ValueNumber
 * @see ValueNumberFrame
 * @see ValueNumberreplacedysis
 * @author David Hovemeyer
 */
public clreplaced ValueNumberFrameModelingVisitor extends AbstractFrameModelingVisitor<ValueNumber, ValueNumberFrame> implements Debug, ValueNumberreplacedysisFeatures {

    /*
     * ----------------------------------------------------------------------
     * Fields
     * ----------------------------------------------------------------------
     */
    private final MethodGen methodGen;

    ValueNumberFactory factory;

    private final ValueNumberCache cache;

    private final LoadedFieldSet loadedFieldSet;

    private final HashMap<Object, ValueNumber> constantValueMap;

    private final HashMap<ValueNumber, String> stringConstantMap;

    private InstructionHandle handle;

    private static final ValueNumber[] EMPTY_INPUT_VALUE_LIST = new ValueNumber[0];

    /*
     * ----------------------------------------------------------------------
     * Public interface
     * ----------------------------------------------------------------------
     */
    /**
     * Constructor.
     *
     * @param methodGen
     *            the method being replacedyzed
     * @param factory
     *            factory for ValueNumbers for the method
     * @param cache
     *            cache of input/output transformations for each instruction
     * @param loadedFieldSet
     *            fields loaded/stored by each instruction and entire method
     * @param lookupFailureCallback
     *            callback to use to report clreplaced lookup failures
     */
    public ValueNumberFrameModelingVisitor(MethodGen methodGen, ValueNumberFactory factory, ValueNumberCache cache, LoadedFieldSet loadedFieldSet, RepositoryLookupFailureCallback lookupFailureCallback) {
        super(methodGen.getConstantPool());
        this.methodGen = methodGen;
        this.factory = factory;
        this.cache = cache;
        this.loadedFieldSet = loadedFieldSet;
        this.constantValueMap = new HashMap<>();
        this.stringConstantMap = new HashMap<>();
    }

    @Override
    public ValueNumber getDefaultValue() {
        return factory.createFreshValue();
    }

    /**
     * Set the instruction handle of the instruction currently being visited.
     * This must be called before the instruction accepts this visitor!
     */
    public void setHandle(InstructionHandle handle) {
        this.handle = handle;
    }

    /*
     * ----------------------------------------------------------------------
     * Instruction modeling
     * ----------------------------------------------------------------------
     */
    /**
     * Determine whether redundant load elimination should be performed for the
     * heap location referenced by the current instruction.
     *
     * @return true if we should do redundant load elimination for the current
     *         instruction, false if not
     */
    private boolean doRedundantLoadElimination() {
        if (!REDUNDANT_LOAD_ELIMINATION) {
            return false;
        }
        XField xfield = loadedFieldSet.getField(handle);
        if (xfield == null) {
            return false;
        }
        // TODO: support two-slot fields
        return !(xfield.getSignature().equals("D") || xfield.getSignature().equals("J"));
    }

    /**
     * Determine whether forward subsreplacedution should be performed for the heap
     * location referenced by the current instruction.
     *
     * @return true if we should do forward subsreplacedution for the current
     *         instruction, false if not
     */
    private boolean doForwardSubsreplacedution() {
        if (!REDUNDANT_LOAD_ELIMINATION) {
            return false;
        }
        XField xfield = loadedFieldSet.getField(handle);
        if (xfield == null) {
            return false;
        }
        if (xfield.getSignature().equals("D") || xfield.getSignature().equals("J")) {
            return false;
        }
        // Don't do forward subsreplacedution for fields that
        // are never read.
        return loadedFieldSet.isLoaded(xfield);
    }

    private void checkConsumedAndProducedValues(Instruction ins, ValueNumber[] consumedValueList, ValueNumber[] producedValueList) {
        int numConsumed = ins.consumeStack(getCPG());
        int numProduced = ins.produceStack(getCPG());
        if (numConsumed == Const.UNPREDICTABLE) {
            throw new InvalidBytecodeException("Unpredictable stack consumption for " + ins);
        }
        if (numProduced == Const.UNPREDICTABLE) {
            throw new InvalidBytecodeException("Unpredictable stack production for " + ins);
        }
        if (consumedValueList.length != numConsumed) {
            throw new IllegalStateException("Wrong number of values consumed for " + ins + ": expected " + numConsumed + ", got " + consumedValueList.length);
        }
        if (producedValueList.length != numProduced) {
            throw new IllegalStateException("Wrong number of values produced for " + ins + ": expected " + numProduced + ", got " + producedValueList.length);
        }
    }

    /**
     * This is the default instruction modeling method.
     */
    @Override
    public void modelNormalInstruction(Instruction ins, int numWordsConsumed, int numWordsProduced) {
        int flags = 0;
        if (ins instanceof InvokeInstruction) {
            flags = ValueNumber.RETURN_VALUE;
        } else if (ins instanceof ArrayInstruction) {
            flags = ValueNumber.ARRAY_VALUE;
        } else if (ins instanceof ConstantPushInstruction) {
            flags = ValueNumber.CONSTANT_VALUE;
        }
        // Get the input operands to this instruction.
        ValueNumber[] inputValueList = popInputValues(numWordsConsumed);
        // See if we have the output operands in the cache.
        // If not, push default (fresh) values for the output,
        // and add them to the cache.
        ValueNumber[] outputValueList = getOutputValues(inputValueList, numWordsProduced, flags);
        if (VERIFY_INTEGRITY) {
            checkConsumedAndProducedValues(ins, inputValueList, outputValueList);
        }
        // Push output operands on stack.
        pushOutputValues(outputValueList);
    }

    @Override
    public void visitGETFIELD(GETFIELD obj) {
        XField xfield = Hierarchy.findXField(obj, getCPG());
        if (xfield != null) {
            if (xfield.isVolatile()) {
                getFrame().killAllLoads();
            }
            if (doRedundantLoadElimination()) {
                loadInstanceField(xfield, obj);
                return;
            }
        }
        handleNormalInstruction(obj);
    }

    @Override
    public void visitPUTFIELD(PUTFIELD obj) {
        if (doForwardSubsreplacedution()) {
            XField xfield = Hierarchy.findXField(obj, getCPG());
            if (xfield != null) {
                storeInstanceField(xfield, obj, false);
                return;
            }
        }
        handleNormalInstruction(obj);
    }

    @Override
    public void visitGETSTATIC(GETSTATIC obj) {
        ConstantPoolGen cpg = getCPG();
        String fieldName = obj.getName(cpg);
        String fieldSig = obj.getSignature(cpg);
        ValueNumberFrame frame = getFrame();
        if (RLE_DEBUG) {
            System.out.println("GETSTATIC of " + fieldName + " : " + fieldSig);
        }
        // Is this an access of a Clreplaced object?
        if (fieldName.startsWith("clreplaced$") && "Ljava/lang/Clreplaced;".equals(fieldSig)) {
            String clreplacedName = fieldName.substring("clreplaced$".length()).replace('$', '.');
            if (RLE_DEBUG) {
                System.out.println("[found load of clreplaced object " + clreplacedName + "]");
            }
            ValueNumber value = factory.getClreplacedObjectValue(clreplacedName);
            frame.pushValue(value);
            return;
        }
        XField xfield = Hierarchy.findXField(obj, getCPG());
        if (xfield != null) {
            if (xfield.isVolatile()) {
                getFrame().killAllLoads();
            }
            if (doRedundantLoadElimination()) {
                loadStaticField(xfield, obj);
                return;
            }
        }
        handleNormalInstruction(obj);
    }

    @Override
    public void visitPUTSTATIC(PUTSTATIC obj) {
        if (doForwardSubsreplacedution()) {
            XField xfield = Hierarchy.findXField(obj, getCPG());
            if (xfield != null) {
                storeStaticField(xfield, obj, false);
                return;
            }
        }
        handleNormalInstruction(obj);
    }

    @Override
    public void visitINVOKESTATIC(INVOKESTATIC obj) {
        if (REDUNDANT_LOAD_ELIMINATION) {
            ConstantPoolGen cpg = getCPG();
            String targetClreplacedName = obj.getClreplacedName(cpg);
            String methodName = obj.getName(cpg);
            String methodSig = obj.getSignature(cpg);
            if (("forName".equals(methodName) && "java.lang.Clreplaced".equals(targetClreplacedName) || "clreplaced$".equals(methodName)) && "(Ljava/lang/String;)Ljava/lang/Clreplaced;".equals(methodSig)) {
                // Access of a Clreplaced object
                ValueNumberFrame frame = getFrame();
                try {
                    ValueNumber arg = frame.getTopValue();
                    String clreplacedName = stringConstantMap.get(arg);
                    if (clreplacedName != null) {
                        frame.popValue();
                        if (RLE_DEBUG) {
                            System.out.println("[found access of clreplaced object " + clreplacedName + "]");
                        }
                        frame.pushValue(factory.getClreplacedObjectValue(clreplacedName));
                        return;
                    }
                } catch (DataflowreplacedysisException e) {
                    throw new InvalidBytecodeException("stack underflow", methodGen, handle, e);
                }
            } else if (Hierarchy.isInnerClreplacedAccess(obj, cpg)) {
                // Possible access of field via an inner-clreplaced access method
                XField xfield = loadedFieldSet.getField(handle);
                if (xfield != null) {
                    if (loadedFieldSet.instructionIsLoad(handle)) {
                        // Load via inner-clreplaced accessor
                        if (doRedundantLoadElimination()) {
                            if (xfield.isStatic()) {
                                loadStaticField(xfield, obj);
                            } else {
                                loadInstanceField(xfield, obj);
                            }
                            return;
                        }
                    } else {
                        // Store via inner-clreplaced accessor
                        if (doForwardSubsreplacedution()) {
                            // Some inner clreplaced access store methods
                            // return the value stored.
                            boolean pushValue = !methodSig.endsWith(")V");
                            if (xfield.isStatic()) {
                                storeStaticField(xfield, obj, pushValue);
                            } else {
                                storeInstanceField(xfield, obj, pushValue);
                            }
                            return;
                        }
                    }
                }
            }
        }
        handleNormalInstruction(obj);
    }

    private void killLoadsOfObjectsPreplaceded(INVOKEDYNAMIC ins) {
        try {
            int preplaceded = getNumWordsConsumed(ins);
            ValueNumber[] arguments = allocateValueNumberArray(preplaceded);
            getFrame().getTopStackWords(arguments);
            for (ValueNumber v : arguments) {
                getFrame().killAllLoadsOf(v);
            }
        } catch (DataflowreplacedysisException e) {
            replacedysisContext.logError("Error in killLoadsOfObjectsPreplaceded", e);
        }
    }

    private void killLoadsOfObjectsPreplaceded(InvokeInstruction ins) {
        try {
            XMethod called = Hierarchy2.findExactMethod(ins, methodGen.getConstantPool(), Hierarchy.ANY_METHOD);
            if (called != null) {
                NoSideEffectMethodsDatabase nse = Global.getreplacedysisCache().getOptionalDatabase(NoSideEffectMethodsDatabase.clreplaced);
                if (nse != null && !nse.is(called.getMethodDescriptor(), MethodSideEffectStatus.SE, MethodSideEffectStatus.OBJ)) {
                    return;
                }
            }
            FieldSummary fieldSummary = replacedysisContext.currentreplacedysisContext().getFieldSummary();
            Set<XField> touched = fieldSummary.getFieldsWritten(called);
            if (!touched.isEmpty()) {
                getFrame().killLoadsOf(touched);
            }
            int preplaceded = getNumWordsConsumed(ins);
            ValueNumber[] arguments = allocateValueNumberArray(preplaceded);
            getFrame().killLoadsWithSimilarName(ins.getClreplacedName(cpg), ins.getMethodName(cpg));
            getFrame().getTopStackWords(arguments);
            for (ValueNumber v : arguments) {
                getFrame().killAllLoadsOf(v);
            }
            // Too many false-positives for primitives without transitive FieldSummary replacedysis,
            // so currently we simply kill any writable primitive on any method call
            // TODO: implement transitive FieldSummary
            getFrame().killAllLoads(true);
        } catch (DataflowreplacedysisException e) {
            replacedysisContext.logError("Error in killLoadsOfObjectsPreplaceded", e);
        }
    }

    @Override
    public void visitMONITORENTER(MONITORENTER obj) {
        // Don't know what this sync invocation is doing.
        // Kill all loads.
        ValueNumber topValue = null;
        try {
            topValue = getFrame().getStackValue(0);
        } catch (DataflowreplacedysisException e) {
            replacedysisContext.logError("error handling monitor enter in value numbering", e);
        }
        getFrame().killAllLoadsExceptFor(topValue);
        handleNormalInstruction(obj);
    }

    public void visitInvokeOnException(Instruction obj) {
        if (!REDUNDANT_LOAD_ELIMINATION || !getFrame().hasAvailableLoads()) {
            return;
        }
        if (obj instanceof INVOKEDYNAMIC) {
            killLoadsOfObjectsPreplaceded((INVOKEDYNAMIC) obj);
            return;
        }
        InvokeInstruction inv = (InvokeInstruction) obj;
        if ((inv instanceof INVOKEINTERFACE || inv instanceof INVOKEVIRTUAL) && inv.getMethodName(cpg).toLowerCase().indexOf("lock") >= 0) {
            // Don't know what this method invocation is doing.
            // Kill all loads.
            getFrame().killAllLoads();
            return;
        }
        if (inv instanceof INVOKEVIRTUAL && "cast".equals(inv.getMethodName(cpg)) && "java.lang.Clreplaced".equals(inv.getClreplacedName(cpg))) {
            // No-op
            return;
        }
        if (inv instanceof INVOKESTATIC) {
            String methodName = inv.getName(cpg);
            if (("forName".equals(methodName) && "java.lang.Clreplaced".equals(inv.getClreplacedName(cpg)) || "clreplaced$".equals(methodName)) && "(Ljava/lang/String;)Ljava/lang/Clreplaced;".equals(inv.getSignature(cpg)) || (Hierarchy.isInnerClreplacedAccess((INVOKESTATIC) inv, cpg) && loadedFieldSet.getField(handle) != null)) {
                return;
            }
        }
        killLoadsOfObjectsPreplaceded(inv);
        if (inv instanceof INVOKESTATIC) {
            getFrame().killAllLoadsOf(null);
        }
    }

    @Override
    public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) {
        if ("cast".equals(obj.getMethodName(cpg)) && "java.lang.Clreplaced".equals(obj.getClreplacedName(cpg))) {
            // treat as no-op
            try {
                ValueNumberFrame frame = getFrame();
                ValueNumber resultType = frame.popValue();
                frame.popValue();
                frame.pushValue(resultType);
            } catch (DataflowreplacedysisException e) {
                replacedysisContext.logError("oops", e);
            }
            return;
        }
        handleNormalInstruction(obj);
    }

    @Override
    public void visitACONST_NULL(ACONST_NULL obj) {
        // Get the input operands to this instruction.
        ValueNumber[] inputValueList = popInputValues(0);
        // See if we have the output operands in the cache.
        // If not, push default (fresh) values for the output,
        // and add them to the cache.
        ValueNumber[] outputValueList = getOutputValues(inputValueList, 1, ValueNumber.CONSTANT_VALUE);
        if (VERIFY_INTEGRITY) {
            checkConsumedAndProducedValues(obj, inputValueList, outputValueList);
        }
        // Push output operands on stack.
        pushOutputValues(outputValueList);
    }

    @Override
    public void visitLDC(LDC obj) {
        Object constantValue = obj.getValue(cpg);
        ValueNumber value;
        if (constantValue instanceof ConstantClreplaced) {
            ConstantClreplaced constantClreplaced = (ConstantClreplaced) constantValue;
            String clreplacedName = constantClreplaced.getBytes(cpg.getConstantPool());
            value = factory.getClreplacedObjectValue(clreplacedName);
        } else if (constantValue instanceof ObjectType) {
            ObjectType objectType = (ObjectType) constantValue;
            String clreplacedName = objectType.getClreplacedName();
            value = factory.getClreplacedObjectValue(clreplacedName);
        } else {
            value = constantValueMap.get(constantValue);
            if (value == null) {
                value = factory.createFreshValue(ValueNumber.CONSTANT_VALUE);
                constantValueMap.put(constantValue, value);
                // Keep track of String constants
                if (constantValue instanceof String) {
                    stringConstantMap.put(value, (String) constantValue);
                }
            }
        }
        getFrame().pushValue(value);
    }

    @Override
    public void visitIINC(IINC obj) {
        if (obj.getIncrement() == 0) {
            // A no-op.
            return;
        }
        // IINC is a special case because its input and output are not on the
        // stack.
        // However, we still want to use the value number cache to ensure that
        // this operation is modeled consistently. (If we do nothing, we miss
        // the fact that the referenced local is modified.)
        int local = obj.getIndex();
        ValueNumber[] input = new ValueNumber[] { getFrame().getValue(local) };
        ValueNumberCache.Entry entry = new ValueNumberCache.Entry(handle, input);
        ValueNumber[] output = cache.lookupOutputValues(entry);
        if (output == null) {
            output = new ValueNumber[] { factory.createFreshValue() };
            cache.addOutputValues(entry, output);
        }
        getFrame().setValue(local, output[0]);
    }

    @Override
    public void visitCHECKCAST(CHECKCAST obj) {
    // Do nothing
    }

    /*
     * ----------------------------------------------------------------------
     * Implementation
     * ----------------------------------------------------------------------
     */
    /**
     * Pop the input values for the given instruction from the current frame.
     */
    private ValueNumber[] popInputValues(int numWordsConsumed) {
        ValueNumberFrame frame = getFrame();
        ValueNumber[] inputValueList = allocateValueNumberArray(numWordsConsumed);
        // Pop off the input operands.
        try {
            frame.getTopStackWords(inputValueList);
            while (numWordsConsumed-- > 0) {
                frame.popValue();
            }
        } catch (DataflowreplacedysisException e) {
            throw new InvalidBytecodeException("Error getting input operands", e);
        }
        return inputValueList;
    }

    /**
     * Push given output values onto the current frame.
     */
    private void pushOutputValues(ValueNumber[] outputValueList) {
        ValueNumberFrame frame = getFrame();
        for (ValueNumber aOutputValueList : outputValueList) {
            frame.pushValue(aOutputValueList);
        }
    }

    /**
     * Get output values for current instruction from the ValueNumberCache.
     */
    private ValueNumber[] getOutputValues(ValueNumber[] inputValueList, int numWordsProduced) {
        return getOutputValues(inputValueList, numWordsProduced, 0);
    }

    private ValueNumber[] getOutputValues(ValueNumber[] inputValueList, int numWordsProduced, int flags) {
        ValueNumberCache.Entry entry = new ValueNumberCache.Entry(handle, inputValueList);
        ValueNumber[] outputValueList = cache.lookupOutputValues(entry);
        if (outputValueList == null) {
            outputValueList = allocateValueNumberArray(numWordsProduced);
            for (int i = 0; i < numWordsProduced; ++i) {
                ValueNumber freshValue = factory.createFreshValue(flags);
                outputValueList[i] = freshValue;
            }
            /*
            if (false && RLE_DEBUG) {
                System.out.println("<<cache fill for " + handle.getPosition() + ": " + vlts(inputValueList) + " ==> "
                        + vlts(outputValueList) + ">>");
            }
             */
            cache.addOutputValues(entry, outputValueList);
        }
        /* else if (false && RLE_DEBUG) {
            System.out.println("<<cache hit for " + handle.getPosition() + ": " + vlts(inputValueList) + " ==> "
                    + vlts(outputValueList) + ">>");
          } */
        return outputValueList;
    }

    /**
     * Creates a new empty array (if needed) with given size.
     *
     * @param size
     *            array size
     * @return if size is zero, returns {@link #EMPTY_INPUT_VALUE_LIST}
     */
    private static ValueNumber[] allocateValueNumberArray(int size) {
        if (size == 0) {
            return EMPTY_INPUT_VALUE_LIST;
        }
        return new ValueNumber[size];
    }

    private static String vlts(ValueNumber[] vl) {
        StringBuilder buf = new StringBuilder();
        for (ValueNumber aVl : vl) {
            if (buf.length() > 0) {
                buf.append(',');
            }
            buf.append(aVl.getNumber());
        }
        return buf.toString();
    }

    /**
     * Load an instance field.
     *
     * @param instanceField
     *            the field
     * @param obj
     *            the Instruction loading the field
     */
    private void loadInstanceField(XField instanceField, Instruction obj) {
        if (RLE_DEBUG) {
            System.out.println("[loadInstanceField for field " + instanceField + " in instruction " + handle);
        }
        ValueNumberFrame frame = getFrame();
        try {
            ValueNumber reference = frame.popValue();
            AvailableLoad availableLoad = new AvailableLoad(reference, instanceField);
            if (RLE_DEBUG) {
                System.out.println("[getfield of " + availableLoad + "]");
            }
            ValueNumber[] loadedValue = frame.getAvailableLoad(availableLoad);
            if (loadedValue == null) {
                // Get (or create) the cached result for this instruction
                ValueNumber[] inputValueList = new ValueNumber[] { reference };
                loadedValue = getOutputValues(inputValueList, getNumWordsProduced(obj));
                // Make the load available
                frame.addAvailableLoad(availableLoad, loadedValue);
                if (RLE_DEBUG) {
                    System.out.println("[Making load available " + availableLoad + " <- " + vlts(loadedValue) + "]");
                }
            } else {
                // Found an available load!
                if (RLE_DEBUG) {
                    System.out.println("[Found available load " + availableLoad + " <- " + vlts(loadedValue) + "]");
                }
            }
            pushOutputValues(loadedValue);
            if (VERIFY_INTEGRITY) {
                checkConsumedAndProducedValues(obj, new ValueNumber[] { reference }, loadedValue);
            }
        } catch (DataflowreplacedysisException e) {
            throw new InvalidBytecodeException("Error loading from instance field", e);
        }
    }

    /**
     * Load a static field.
     *
     * @param staticField
     *            the field
     * @param obj
     *            the Instruction loading the field
     */
    private void loadStaticField(XField staticField, Instruction obj) {
        if (RLE_DEBUG) {
            System.out.println("[loadStaticField for field " + staticField + " in instruction " + handle);
        }
        ValueNumberFrame frame = getFrame();
        AvailableLoad availableLoad = new AvailableLoad(staticField);
        ValueNumber[] loadedValue = frame.getAvailableLoad(availableLoad);
        if (loadedValue == null) {
            // Make the load available
            int numWordsProduced = getNumWordsProduced(obj);
            loadedValue = getOutputValues(EMPTY_INPUT_VALUE_LIST, numWordsProduced);
            frame.addAvailableLoad(availableLoad, loadedValue);
            if (RLE_DEBUG) {
                System.out.println("[making load of " + staticField + " available]");
            }
        } else {
            if (RLE_DEBUG) {
                System.out.println("[found available load of " + staticField + "]");
            }
        }
        if (VERIFY_INTEGRITY) {
            checkConsumedAndProducedValues(obj, EMPTY_INPUT_VALUE_LIST, loadedValue);
        }
        pushOutputValues(loadedValue);
    }

    /**
     * Store an instance field.
     *
     * @param instanceField
     *            the field
     * @param obj
     *            the instruction which stores the field
     * @param pushStoredValue
     *            push the stored value onto the stack (because we are modeling
     *            an inner-clreplaced field access method)
     */
    private void storeInstanceField(XField instanceField, Instruction obj, boolean pushStoredValue) {
        if (RLE_DEBUG) {
            System.out.println("[storeInstanceField for field " + instanceField + " in instruction " + handle);
        }
        ValueNumberFrame frame = getFrame();
        int numWordsConsumed = getNumWordsConsumed(obj);
        /*
         * System.out.println("Instruction is " + handle);
         * System.out.println("numWordsConsumed="+numWordsConsumed);
         */
        ValueNumber[] inputValueList = popInputValues(numWordsConsumed);
        ValueNumber reference = inputValueList[0];
        ValueNumber[] storedValue = allocateValueNumberArray(inputValueList.length - 1);
        System.arraycopy(inputValueList, 1, storedValue, 0, inputValueList.length - 1);
        if (pushStoredValue) {
            pushOutputValues(storedValue);
        }
        // Kill all previous loads of the same field,
        // in case there is aliasing we don't know about
        frame.killLoadsOfField(instanceField);
        // Forward subsreplacedution
        frame.addAvailableLoad(new AvailableLoad(reference, instanceField), storedValue);
        if (RLE_DEBUG) {
            System.out.println("[making store of " + instanceField + " available]");
        }
        if (VERIFY_INTEGRITY) {
            /*
             * System.out.println("pushStoredValue="+pushStoredValue);
             */
            checkConsumedAndProducedValues(obj, inputValueList, pushStoredValue ? storedValue : EMPTY_INPUT_VALUE_LIST);
        }
    }

    /**
     * Store a static field.
     *
     * @param staticField
     *            the static field
     * @param obj
     *            the instruction which stores the field
     * @param pushStoredValue
     *            push the stored value onto the stack (because we are modeling
     *            an inner-clreplaced field access method)
     */
    private void storeStaticField(XField staticField, Instruction obj, boolean pushStoredValue) {
        if (RLE_DEBUG) {
            System.out.println("[storeStaticField for field " + staticField + " in instruction " + handle);
        }
        ValueNumberFrame frame = getFrame();
        AvailableLoad availableLoad = new AvailableLoad(staticField);
        int numWordsConsumed = getNumWordsConsumed(obj);
        ValueNumber[] inputValueList = popInputValues(numWordsConsumed);
        if (pushStoredValue) {
            pushOutputValues(inputValueList);
        }
        // Kill loads of this field
        frame.killLoadsOfField(staticField);
        // Make load available
        frame.addAvailableLoad(availableLoad, inputValueList);
        if (RLE_DEBUG) {
            System.out.println("[making store of " + staticField + " available]");
        }
        if (VERIFY_INTEGRITY) {
            checkConsumedAndProducedValues(obj, inputValueList, pushStoredValue ? inputValueList : EMPTY_INPUT_VALUE_LIST);
        }
    }
}

19 View Complete Implementation : Pass3bVerifier.java
Copyright Apache License 2.0
Author : apache
/**
 * Throws an exception indicating the returned type is not compatible with the return type of the given method.
 *
 * @param returnedType the type of the returned expression
 * @param m the method we are processing
 * @throws StructuralCodeConstraintException always
 * @since 6.0
 */
public void invalidReturnTypeError(final Type returnedType, final MethodGen m) {
    throw new StructuralCodeConstraintException("Returned type " + returnedType + " does not match Method's return type " + m.getReturnType());
}

19 View Complete Implementation : BugAccumulator.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
public void acreplacedulateBug(BugInstance bug, ClreplacedContext clreplacedContext, MethodGen methodGen, String sourceFile, Location location) {
    acreplacedulateBug(bug, SourceLineAnnotation.fromVisitedInstruction(clreplacedContext, methodGen, sourceFile, location.getHandle()));
}

19 View Complete Implementation : BCELifier.java
Copyright GNU General Public License v3.0
Author : contra
public void visitMethod(Method method) {
    MethodGen mg = new MethodGen(method, _clazz.getClreplacedName(), _cp);
    Type result_type = mg.getReturnType();
    Type[] arg_types = mg.getArgumentTypes();
    _out.println("    InstructionList il = new InstructionList();");
    _out.println("    MethodGen method = new MethodGen(" + printFlags(method.getAccessFlags()) + ", " + printType(result_type) + ", " + printArgumentTypes(arg_types) + ", " + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true) + " }, \"" + method.getName() + "\", \"" + _clazz.getClreplacedName() + "\", il, _cp);\n");
    BCELFactory factory = new BCELFactory(mg, _out);
    factory.start();
    _out.println("    method.setMaxStack();");
    _out.println("    method.setMaxLocals();");
    _out.println("    _cg.addMethod(method.getMethod());");
    _out.println("    il.dispose();");
}

19 View Complete Implementation : FindSqlInjection.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
private BugInstance generateBugInstance(JavaClreplaced javaClreplaced, MethodGen methodGen, InstructionHandle handle, StringAppendState stringAppendState, boolean isExecute) {
    int priority = LOW_PRIORITY;
    boolean sawSeriousTaint = false;
    if (stringAppendState.getSawAppend(handle)) {
        if (stringAppendState.getSawOpenQuote(handle) && stringAppendState.getSawCloseQuote(handle)) {
            priority = HIGH_PRIORITY;
        } else if (stringAppendState.getSawComma(handle)) {
            priority = NORMAL_PRIORITY;
        }
        if (!stringAppendState.getSawUnsafeAppend(handle)) {
            priority += 2;
        } else if (stringAppendState.getSawSeriousTaint(handle)) {
            priority--;
            sawSeriousTaint = true;
        } else if (!stringAppendState.getSawTaint(handle)) {
            priority++;
        }
    }
    String description;
    if (isExecute) {
        description = "SQL_NONCONSTANT_STRING_PreplacedED_TO_EXECUTE";
    } else {
        description = "SQL_PREPARED_STATEMENT_GENERATED_FROM_NONCONSTANT_STRING";
    }
    BugInstance bug = new BugInstance(this, description, priority);
    bug.addClreplacedAndMethod(methodGen, javaClreplaced.getSourceFileName());
    if (sawSeriousTaint) {
        bug.addString("non-constant SQL string involving HTTP taint");
    }
    return bug;
}

19 View Complete Implementation : id.java
Copyright Apache License 2.0
Author : apache
public static void main(final String[] argv) throws Exception {
    JavaClreplaced clazz;
    if ((clazz = Repository.lookupClreplaced(argv[0])) == null) {
        // May throw IOException
        clazz = new ClreplacedParser(argv[0]).parse();
    }
    final ClreplacedGen cg = new ClreplacedGen(clazz);
    for (final Method method : clazz.getMethods()) {
        final MethodGen mg = new MethodGen(method, cg.getClreplacedName(), cg.getConstantPool());
        cg.replaceMethod(method, mg.getMethod());
    }
    for (final Field field : clazz.getFields()) {
        final FieldGen fg = new FieldGen(field, cg.getConstantPool());
        cg.replaceField(field, fg.getField());
    }
    cg.getJavaClreplaced().dump(clazz.getClreplacedName() + ".clazz");
}

19 View Complete Implementation : ASTInteger.java
Copyright Apache License 2.0
Author : apache
/**
 * Fifth preplaced, produce Java byte code.
 */
@Override
public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
    il.append(new PUSH(cp, value));
    ASTFunDecl.push();
}

19 View Complete Implementation : maxstack.java
Copyright Apache License 2.0
Author : apache
public static void main(final String[] argv) throws Exception {
    for (final String clreplaced_name : argv) {
        JavaClreplaced java_clreplaced = Repository.lookupClreplaced(clreplaced_name);
        if (java_clreplaced == null) {
            java_clreplaced = new ClreplacedParser(clreplaced_name).parse();
        }
        final ConstantPoolGen cp = new ConstantPoolGen(java_clreplaced.getConstantPool());
        for (final Method m : java_clreplaced.getMethods()) {
            if (!(m.isAbstract() || m.isNative())) {
                final MethodGen mg = new MethodGen(m, clreplaced_name, cp);
                final int compiled_stack = mg.getMaxStack();
                final int compiled_locals = mg.getMaxLocals();
                // Recompute value
                mg.setMaxStack();
                mg.setMaxLocals();
                final int computed_stack = mg.getMaxStack();
                final int computed_locals = mg.getMaxLocals();
                // Reuse instruction handles
                mg.getInstructionList().dispose();
                System.out.println(m);
                if (computed_stack == compiled_stack) {
                    System.out.println("Stack ok(" + computed_stack + ")");
                } else {
                    System.out.println("\nCompiled stack size " + compiled_stack + " computed size " + computed_stack);
                }
                if (computed_locals == compiled_locals) {
                    System.out.println("Locals ok(" + computed_locals + ")");
                } else {
                    System.out.println("\nCompiled locals " + compiled_locals + " computed size " + computed_locals);
                }
            }
        }
    }
}

19 View Complete Implementation : ASTProgram.java
Copyright Apache License 2.0
Author : apache
/**
 * Fifth preplaced, produce Java byte code.
 */
public void byte_code(final ClreplacedGen clreplaced_gen, final ConstantPoolGen cp) {
    /* private static BufferedReader _in;
     */
    clreplaced_gen.addField(new Field(ACC_PRIVATE | ACC_STATIC, cp.addUtf8("_in"), cp.addUtf8("Ljava/io/BufferedReader;"), null, cp.getConstantPool()));
    MethodGen method;
    InstructionList il = new InstructionList();
    final String clreplaced_name = clreplaced_gen.getClreplacedName();
    /* Often used constant pool entries
     */
    final int _in = cp.addFieldref(clreplaced_name, "_in", "Ljava/io/BufferedReader;");
    final int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
    il.append(new GETSTATIC(out));
    il.append(new PUSH(cp, "Please enter a number> "));
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.io.PrintStream", "print", "(Ljava/lang/String;)V")));
    il.append(new GETSTATIC(_in));
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.io.BufferedReader", "readLine", "()Ljava/lang/String;")));
    il.append(new INVOKESTATIC(cp.addMethodref("java.lang.Integer", "parseInt", "(Ljava/lang/String;)I")));
    il.append(InstructionConstants.IRETURN);
    /* private static int _readInt() throws IOException
     */
    method = new MethodGen(ACC_STATIC | ACC_PRIVATE | ACC_FINAL, Type.INT, Type.NO_ARGS, null, "_readInt", clreplaced_name, il, cp);
    method.addException("java.io.IOException");
    method.setMaxStack(2);
    clreplaced_gen.addMethod(method.getMethod());
    /* private static int _writeInt(int i) throws IOException
     */
    final Type[] args = { Type.INT };
    final String[] argv = { "i" };
    il = new InstructionList();
    il.append(new GETSTATIC(out));
    il.append(new NEW(cp.addClreplaced("java.lang.StringBuffer")));
    il.append(InstructionConstants.DUP);
    il.append(new PUSH(cp, "Result: "));
    il.append(new INVOKESPECIAL(cp.addMethodref("java.lang.StringBuffer", "<init>", "(Ljava/lang/String;)V")));
    il.append(new ILOAD(0));
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.lang.StringBuffer", "append", "(I)Ljava/lang/StringBuffer;")));
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.lang.StringBuffer", "toString", "()Ljava/lang/String;")));
    il.append(new INVOKEVIRTUAL(cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V")));
    il.append(new PUSH(cp, 0));
    // Reuse objects, if possible
    il.append(InstructionConstants.IRETURN);
    method = new MethodGen(ACC_STATIC | ACC_PRIVATE | ACC_FINAL, Type.INT, args, argv, "_writeInt", clreplaced_name, il, cp);
    method.setMaxStack(4);
    clreplaced_gen.addMethod(method.getMethod());
    /* public <init> -- constructor
     */
    // Dispose instruction handles for better memory utilization
    il.dispose();
    il = new InstructionList();
    // Push `this'
    il.append(new ALOAD(0));
    il.append(new INVOKESPECIAL(cp.addMethodref("java.lang.Object", "<init>", "()V")));
    il.append(new RETURN());
    method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, null, "<init>", clreplaced_name, il, cp);
    method.setMaxStack(1);
    clreplaced_gen.addMethod(method.getMethod());
    /* clreplaced initializer
     */
    // Dispose instruction handles for better memory utilization
    il.dispose();
    il = new InstructionList();
    il.append(new NEW(cp.addClreplaced("java.io.BufferedReader")));
    il.append(InstructionConstants.DUP);
    il.append(new NEW(cp.addClreplaced("java.io.InputStreamReader")));
    il.append(InstructionConstants.DUP);
    il.append(new GETSTATIC(cp.addFieldref("java.lang.System", "in", "Ljava/io/InputStream;")));
    il.append(new INVOKESPECIAL(cp.addMethodref("java.io.InputStreamReader", "<init>", "(Ljava/io/InputStream;)V")));
    il.append(new INVOKESPECIAL(cp.addMethodref("java.io.BufferedReader", "<init>", "(Ljava/io/Reader;)V")));
    il.append(new PUTSTATIC(_in));
    // Reuse instruction constants
    il.append(InstructionConstants.RETURN);
    method = new MethodGen(ACC_STATIC, Type.VOID, Type.NO_ARGS, null, "<clinit>", clreplaced_name, il, cp);
    method.setMaxStack(5);
    clreplaced_gen.addMethod(method.getMethod());
    for (int i = 0; i < fun_decls.length; i++) {
        fun_decls[i].byte_code(clreplaced_gen, cp);
    }
}

19 View Complete Implementation : PLSETestCase.java
Copyright Apache License 2.0
Author : apache
/**
 * BCEL-208: A couple of methods in MethodGen.java need to test for
 * an empty instruction list.
 */
public void testB208() throws ClreplacedNotFoundException {
    final JavaClreplaced clazz = getTestClreplaced(PACKAGE_BASE_NAME + ".data.PLSETestClreplaced");
    final ClreplacedGen gen = new ClreplacedGen(clazz);
    final ConstantPoolGen pool = gen.getConstantPool();
    final Method m = gen.getMethodAt(1);
    final MethodGen mg = new MethodGen(m, gen.getClreplacedName(), pool);
    mg.setInstructionList(null);
    mg.addLocalVariable("local2", Type.INT, null, null);
    // currently, this will cause null pointer exception
    mg.getLocalVariableTable(pool);
}

19 View Complete Implementation : CFG.java
Copyright GNU Lesser General Public License v2.1
Author : spotbugs
/**
 * Simple control flow graph abstraction for BCEL.
 *
 * @see BasicBlock
 * @see Edge
 */
public clreplaced CFG extends AbstractGraph<Edge, BasicBlock> implements Debug {

    /*
     * ----------------------------------------------------------------------
     * CFG flags
     * ----------------------------------------------------------------------
     */
    /**
     * Flag set if infeasible exception edges have been pruned from the CFG.
     */
    public static final int PRUNED_INFEASIBLE_EXCEPTIONS = 1;

    /**
     * Flag set if normal return edges from calls to methods which
     * unconditionally throw an exception have been removed.
     */
    public static final int PRUNED_UNCONDITIONAL_THROWERS = 2;

    /**
     * Flag set if CFG has been "refined"; i.e., to the extent possible, all
     * infeasible edges have been removed.
     */
    public static final int REFINED = 4;

    /**
     * Flag set if CFG edges corresponding to failed replacedertions have been
     * removed.
     */
    public static final int PRUNED_FAILED_replacedERTION_EDGES = 8;

    /**
     * Flag set if CFG is busy (in the process of being refined.
     */
    public static final int BUSY = 16;

    public static final int FOUND_INEXACT_UNCONDITIONAL_THROWERS = 32;

    /*
     * ----------------------------------------------------------------------
     * Helper clreplacedes
     * ----------------------------------------------------------------------
     */
    /**
     * An Iterator over the Locations in the CFG. Because of JSR subroutines,
     * the same instruction may actually be part of multiple basic blocks (with
     * different facts true in each, due to calling context). Locations specify
     * both the instruction and the basic block.
     */
    private clreplaced LocationIterator implements Iterator<Location> {

        private final Iterator<BasicBlock> blockIter;

        private BasicBlock curBlock;

        private Iterator<InstructionHandle> instructionIter;

        private Location next;

        private LocationIterator() {
            this.blockIter = blockIterator();
            findNext();
        }

        @Override
        public boolean hasNext() {
            findNext();
            return next != null;
        }

        @Override
        public Location next() {
            findNext();
            if (next == null) {
                throw new NoSuchElementException();
            }
            Location result = next;
            next = null;
            return result;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

        private void findNext() {
            while (next == null) {
                // Make sure we have an instruction iterator
                if (instructionIter == null) {
                    if (!blockIter.hasNext()) {
                        // At end
                        return;
                    }
                    curBlock = blockIter.next();
                    instructionIter = curBlock.instructionIterator();
                }
                if (instructionIter.hasNext()) {
                    next = new Location(instructionIter.next(), curBlock);
                } else {
                    // Go to next block
                    instructionIter = null;
                }
            }
        }
    }

    /*
     * ----------------------------------------------------------------------
     * Fields
     * ----------------------------------------------------------------------
     */
    private BasicBlock entry, exit;

    private int flags;

    // for informational purposes
    private String methodName;

    private MethodGen methodGen;

    private List<Edge> removedEdgeList;

    /*
     * ----------------------------------------------------------------------
     * Public methods
     * ----------------------------------------------------------------------
     */
    /**
     * Constructor. Creates empty control flow graph (with just entry and exit
     * nodes).
     */
    public CFG() {
    }

    /**
     * @param methodName
     *            The methodName to set.
     */
    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public void setMethodGen(MethodGen methodGen) {
        this.methodGen = methodGen;
    }

    public MethodGen getMethodGen() {
        return methodGen;
    }

    /**
     * @return Returns the methodName.
     */
    public String getMethodName() {
        return methodName;
    }

    public String getMethodSig() {
        return methodGen.getSignature();
    }

    public void setFlags(int flags) {
        this.flags = flags;
    }

    public void setFlag(int flags) {
        this.flags |= flags;
    }

    public void clearFlag(int flags) {
        this.flags &= ~flags;
    }

    public int getFlags() {
        return flags;
    }

    public boolean isFlagSet(int flag) {
        return (flags & flag) != 0;
    }

    /**
     * Get the entry node.
     */
    public BasicBlock getEntry() {
        if (entry == null) {
            entry = allocate();
        }
        return entry;
    }

    /**
     * Get the exit node.
     */
    public BasicBlock getExit() {
        if (exit == null) {
            exit = allocate();
        }
        return exit;
    }

    /**
     * Add a unique edge to the graph. There must be no other edge already in
     * the CFG with the same source and destination blocks.
     *
     * @param source
     *            the source basic block
     * @param dest
     *            the destination basic block
     * @param type
     *            the type of edge; see constants in EdgeTypes interface
     * @return the newly created Edge
     * @throws IllegalStateException
     *             if there is already an edge in the CFG with the same source
     *             and destination block
     */
    public Edge createEdge(BasicBlock source, BasicBlock dest, @Edge.Type int type) {
        Edge edge = createEdge(source, dest);
        edge.setType(type);
        return edge;
    }

    /**
     * Look up an Edge by its id.
     *
     * @param id
     *            the id of the edge to look up
     * @return the Edge, or null if no matching Edge was found
     */
    public Edge lookupEdgeById(int id) {
        Iterator<Edge> i = edgeIterator();
        while (i.hasNext()) {
            Edge edge = i.next();
            if (edge.getId() == id) {
                return edge;
            }
        }
        return null;
    }

    /**
     * Look up a BasicBlock by its unique label.
     *
     * @param blockLabel
     *            the label of a BasicBlock
     * @return the BasicBlock with the given label, or null if there is no such
     *         BasicBlock
     */
    public BasicBlock lookupBlockByLabel(int blockLabel) {
        for (Iterator<BasicBlock> i = blockIterator(); i.hasNext(); ) {
            BasicBlock basicBlock = i.next();
            if (basicBlock.getLabel() == blockLabel) {
                return basicBlock;
            }
        }
        return null;
    }

    /**
     * Get an Iterator over the nodes (BasicBlocks) of the control flow graph.
     */
    public Iterator<BasicBlock> blockIterator() {
        return vertexIterator();
    }

    /*
     * * Get an Iteratable over the nodes (BasicBlocks) of the control flow
     * graph.
     */
    public Iterable<BasicBlock> blocks() {
        return vertices();
    }

    /**
     * Get an Iterator over the Locations in the control flow graph.
     */
    public Iterator<Location> locationIterator() {
        return new LocationIterator();
    }

    /**
     * Get an Iterator over the Locations in the control flow graph.
     */
    public Iterable<Location> locations() {
        return () -> locationIterator();
    }

    /**
     * Returns a collection of locations, ordered according to the compareTo
     * ordering over locations. If you want to list all the locations in a CFG
     * for debugging purposes, this is a good order to do so in.
     *
     * @return collection of locations
     */
    public Collection<Location> orderedLocations() {
        TreeSet<Location> tree = new TreeSet<>();
        for (Iterator<Location> locs = locationIterator(); locs.hasNext(); ) {
            Location loc = locs.next();
            tree.add(loc);
        }
        return tree;
    }

    /**
     * Get Collection of basic blocks whose IDs are specified by given BitSet.
     *
     * @param labelSet
     *            BitSet of block labels
     * @return a Collection containing the blocks whose IDs are given
     */
    public Collection<BasicBlock> getBlocks(BitSet labelSet) {
        LinkedList<BasicBlock> result = new LinkedList<>();
        for (Iterator<BasicBlock> i = blockIterator(); i.hasNext(); ) {
            BasicBlock block = i.next();
            if (labelSet.get(block.getLabel())) {
                result.add(block);
            }
        }
        return result;
    }

    /**
     * Get a Collection of basic blocks which contain the bytecode instruction
     * with given offset.
     *
     * @param offset
     *            the bytecode offset of an instruction
     * @return Collection of BasicBlock objects which contain the instruction
     *         with that offset
     */
    public Collection<BasicBlock> getBlocksContainingInstructionWithOffset(int offset) {
        LinkedList<BasicBlock> result = new LinkedList<>();
        for (Iterator<BasicBlock> i = blockIterator(); i.hasNext(); ) {
            BasicBlock block = i.next();
            if (block.containsInstructionWithOffset(offset)) {
                result.add(block);
            }
        }
        return result;
    }

    /**
     * Get a Collection of Locations which specify the instruction at given
     * bytecode offset.
     *
     * @param offset
     *            the bytecode offset
     * @return all Locations referring to the instruction at that offset
     */
    public Collection<Location> getLocationsContainingInstructionWithOffset(int offset) {
        LinkedList<Location> result = new LinkedList<>();
        for (Iterator<Location> i = locationIterator(); i.hasNext(); ) {
            Location location = i.next();
            if (location.getHandle().getPosition() == offset) {
                result.add(location);
            }
        }
        return result;
    }

    /**
     * Get the first predecessor reachable from given edge type.
     *
     * @param target
     *            the target block
     * @param edgeType
     *            the edge type leading from the predecessor
     * @return the predecessor, or null if there is no incoming edge with the
     *         specified edge type
     */
    public BasicBlock getPredecessorWithEdgeType(BasicBlock target, @Type int edgeType) {
        Edge edge = getIncomingEdgeWithType(target, edgeType);
        return edge != null ? edge.getSource() : null;
    }

    /**
     * Get the first successor reachable from given edge type.
     *
     * @param source
     *            the source block
     * @param edgeType
     *            the edge type leading to the successor
     * @return the successor, or null if there is no outgoing edge with the
     *         specified edge type
     */
    public BasicBlock getSuccessorWithEdgeType(BasicBlock source, @Type int edgeType) {
        Edge edge = getOutgoingEdgeWithType(source, edgeType);
        return edge != null ? edge.getTarget() : null;
    }

    /**
     * Get the Location where exception(s) thrown on given exception edge are
     * thrown.
     *
     * @param exceptionEdge
     *            the exception Edge
     * @return Location where exception(s) are thrown from
     */
    public Location getExceptionThrowerLocation(Edge exceptionEdge) {
        if (!exceptionEdge.isExceptionEdge()) {
            throw new IllegalArgumentException();
        }
        InstructionHandle handle = exceptionEdge.getSource().getExceptionThrower();
        if (handle == null) {
            throw new IllegalStateException();
        }
        BasicBlock basicBlock = (handle.getInstruction() instanceof ATHROW) ? exceptionEdge.getSource() : getSuccessorWithEdgeType(exceptionEdge.getSource(), EdgeTypes.FALL_THROUGH_EDGE);
        if (basicBlock == null && removedEdgeList != null) {
            // The fall-through edge might have been removed during
            // CFG pruning. Look for it in the removed edge list.
            for (Edge removedEdge : removedEdgeList) {
                if (removedEdge.getType() == EdgeTypes.FALL_THROUGH_EDGE && removedEdge.getSource() == exceptionEdge.getSource()) {
                    basicBlock = removedEdge.getTarget();
                    break;
                }
            }
        }
        if (basicBlock == null) {
            throw new IllegalStateException("No basic block for thrower " + handle + " in " + this.methodGen.getClreplacedName() + "." + this.methodName + " : " + this.methodGen.getSignature());
        }
        return new Location(handle, basicBlock);
    }

    /**
     * Get an Iterator over Edges removed from this CFG.
     *
     * @return Iterator over Edges removed from this CFG
     */
    public Iterator<Edge> removedEdgeIterator() {
        return removedEdgeList != null ? removedEdgeList.iterator() : new NullIterator<>();
    }

    /**
     * Get the first incoming edge in basic block with given type.
     *
     * @param basicBlock
     *            the basic block
     * @param edgeType
     *            the edge type
     * @return the Edge, or null if there is no edge with that edge type
     */
    public Edge getIncomingEdgeWithType(BasicBlock basicBlock, @Type int edgeType) {
        return getEdgeWithType(incomingEdgeIterator(basicBlock), edgeType);
    }

    /**
     * Get the first outgoing edge in basic block with given type.
     *
     * @param basicBlock
     *            the basic block
     * @param edgeType
     *            the edge type
     * @return the Edge, or null if there is no edge with that edge type
     */
    public Edge getOutgoingEdgeWithType(BasicBlock basicBlock, @Type int edgeType) {
        return getEdgeWithType(outgoingEdgeIterator(basicBlock), edgeType);
    }

    private Edge getEdgeWithType(Iterator<Edge> iter, @Type int edgeType) {
        while (iter.hasNext()) {
            Edge edge = iter.next();
            if (edge.getType() == edgeType) {
                return edge;
            }
        }
        return null;
    }

    /**
     * Allocate a new BasicBlock. The block won't be connected to any node in
     * the graph.
     */
    public BasicBlock allocate() {
        BasicBlock b = new BasicBlock();
        addVertex(b);
        return b;
    }

    /**
     * Get number of basic blocks. This is just here for compatibility with the
     * old CFG method names.
     */
    public int getNumBasicBlocks() {
        return getNumVertices();
    }

    /**
     * Get the number of edge labels allocated. This is just here for
     * compatibility with the old CFG method names.
     */
    public int getMaxEdgeId() {
        return getNumEdgeLabels();
    }

    public void checkIntegrity() {
        // Ensure that basic blocks have only consecutive instructions
        for (Iterator<BasicBlock> i = blockIterator(); i.hasNext(); ) {
            BasicBlock basicBlock = i.next();
            InstructionHandle prev = null;
            for (Iterator<InstructionHandle> j = basicBlock.instructionIterator(); j.hasNext(); ) {
                InstructionHandle handle = j.next();
                if (prev != null && prev.getNext() != handle) {
                    throw new IllegalStateException("Non-consecutive instructions in block " + basicBlock.getLabel() + ": prev=" + prev + ", handle=" + handle);
                }
                prev = handle;
            }
        }
    }

    @Override
    protected Edge allocateEdge(BasicBlock source, BasicBlock target) {
        return new Edge(source, target);
    }

    /*
     * (non-Javadoc)
     *
     * @see
     * edu.umd.cs.findbugs.graph.AbstractGraph#removeEdge(edu.umd.cs.findbugs
     * .graph.AbstractEdge)
     */
    @Override
    public void removeEdge(Edge edge) {
        super.removeEdge(edge);
        // Keep track of removed edges.
        if (removedEdgeList == null) {
            removedEdgeList = new LinkedList<>();
        }
        removedEdgeList.add(edge);
    }

    /**
     * Get number of non-exception control successors of given basic block.
     *
     * @param block
     *            a BasicBlock
     * @return number of non-exception control successors of the basic block
     */
    public int getNumNonExceptionSucessors(BasicBlock block) {
        int numNonExceptionSuccessors = block.getNumNonExceptionSuccessors();
        if (numNonExceptionSuccessors < 0) {
            numNonExceptionSuccessors = 0;
            for (Iterator<Edge> i = outgoingEdgeIterator(block); i.hasNext(); ) {
                Edge edge = i.next();
                if (!edge.isExceptionEdge()) {
                    numNonExceptionSuccessors++;
                }
            }
            block.setNumNonExceptionSuccessors(numNonExceptionSuccessors);
        }
        return numNonExceptionSuccessors;
    }

    /**
     * Get the Location representing the entry to the CFG. Note that this is a
     * "fake" Location, and shouldn't be relied on to yield source line
     * information.
     *
     * @return Location at entry to CFG
     */
    public Location getLocationAtEntry() {
        InstructionHandle handle = getEntry().getFirstInstruction();
        replacedert handle != null;
        return new Location(handle, getEntry());
    }

    public Location getPreviousLocation(Location loc) {
        InstructionHandle handle = loc.getHandle();
        BasicBlock basicBlock = loc.getBasicBlock();
        if (basicBlock.getFirstInstruction().equals(handle)) {
            BasicBlock prevBlock = basicBlock;
            while (true) {
                prevBlock = getPredecessorWithEdgeType(prevBlock, EdgeTypes.FALL_THROUGH_EDGE);
                if (prevBlock == null) {
                    return loc;
                }
                handle = prevBlock.getLastInstruction();
                if (handle != null) {
                    return new Location(handle, prevBlock);
                }
            }
        } else {
            handle = handle.getPrev();
            return new Location(handle, basicBlock);
        }
    }
}

18 View Complete Implementation : ASTExpr.java
Copyright Apache License 2.0
Author : apache
/**
 * Fifth preplaced, produce Java byte code.
 */
public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
    exprs[0].byte_code(il, method, cp);
    if (unop != -1) {
        // Apply unary operand
        if (unop == MINUS) {
            il.append(InstructionConstants.INEG);
        } else {
            // == NOT
            // Push TRUE
            il.append(new PUSH(cp, 1));
            // Push TRUE
            ASTFunDecl.push();
            il.append(InstructionConstants.IXOR);
            ASTFunDecl.pop();
        }
    } else {
        // Apply binary operand
        BranchHandle bh = null;
        exprs[1].byte_code(il, method, cp);
        switch(kind) {
            case PLUS:
                il.append(InstructionConstants.IADD);
                ASTFunDecl.pop();
                break;
            case MINUS:
                il.append(InstructionConstants.ISUB);
                ASTFunDecl.pop();
                break;
            case MULT:
                il.append(InstructionConstants.IMUL);
                ASTFunDecl.pop();
                break;
            case DIV:
                il.append(InstructionConstants.IDIV);
                ASTFunDecl.pop();
                break;
            case AND:
                il.append(InstructionConstants.IAND);
                ASTFunDecl.pop();
                break;
            case OR:
                il.append(InstructionConstants.IOR);
                ASTFunDecl.pop();
                break;
            /* Use negated operands */
            case EQ:
                bh = il.append(new IF_ICMPNE(null));
                ASTFunDecl.pop(2);
                break;
            case LEQ:
                bh = il.append(new IF_ICMPGT(null));
                ASTFunDecl.pop(2);
                break;
            case GEQ:
                bh = il.append(new IF_ICMPLT(null));
                ASTFunDecl.pop(2);
                break;
            case NEQ:
                bh = il.append(new IF_ICMPEQ(null));
                ASTFunDecl.pop(2);
                break;
            case LT:
                bh = il.append(new IF_ICMPGE(null));
                ASTFunDecl.pop(2);
                break;
            case GT:
                bh = il.append(new IF_ICMPLE(null));
                ASTFunDecl.pop(2);
                break;
            default:
                System.err.println("Ooops");
        }
        switch(kind) {
            case EQ:
            case LEQ:
            case GEQ:
            case NEQ:
            case LT:
            case GT:
                BranchHandle g;
                il.append(new PUSH(cp, 1));
                g = il.append(new GOTO(null));
                bh.setTarget(il.append(new PUSH(cp, 0)));
                // May be optimized away later
                g.setTarget(il.append(InstructionConstants.NOP));
                ASTFunDecl.push();
                break;
            default:
                break;
        }
    }
}

18 View Complete Implementation : ASTIdent.java
Copyright Apache License 2.0
Author : apache
/**
 * Fifth preplaced, produce Java byte code.
 */
@Override
public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
    if (name.equals("TRUE")) {
        il.append(new PUSH(cp, 1));
    } else if (name.equals("FALSE")) {
        il.append(new PUSH(cp, 0));
    } else {
        final LocalVariableGen local_var = reference.getLocalVariable();
        il.append(new ILOAD(local_var.getIndex()));
    }
    ASTFunDecl.push();
}

18 View Complete Implementation : ASTLetExpr.java
Copyright Apache License 2.0
Author : apache
/**
 * Fifth preplaced, produce Java byte code.
 */
@Override
public void byte_code(final InstructionList il, final MethodGen method, final ConstantPoolGen cp) {
    final int size = idents.length;
    final LocalVariableGen[] l = new LocalVariableGen[size];
    for (int i = 0; i < size; i++) {
        final String ident = idents[i].getName();
        final Variable entry = (Variable) env.get(ident);
        final Type t = BasicType.getType((byte) idents[i].getType());
        final LocalVariableGen lg = method.addLocalVariable(ident, t, null, null);
        final int slot = lg.getIndex();
        entry.setLocalVariable(lg);
        InstructionHandle start = il.getEnd();
        exprs[i].byte_code(il, method, cp);
        start = (start == null) ? il.getStart() : start.getNext();
        lg.setStart(start);
        il.append(new ISTORE(slot));
        ASTFunDecl.pop();
        l[i] = lg;
    }
    body.byte_code(il, method, cp);
    final InstructionHandle end = il.getEnd();
    for (int i = 0; i < size; i++) {
        l[i].setEnd(end);
    }
}