/** * Add an InstructionHandle to the basic block. * * @param handle * the InstructionHandle */ public void addInstruction(InstructionHandle handle) { if (firstInstruction == null) { firstInstruction = lastInstruction = handle; } else { if (VERIFY_INTEGRITY && handle != lastInstruction.getNext()) { throw new IllegalStateException("Adding non-consecutive instruction"); } lastInstruction = handle; } }
@Override public InstructionHandle next() { if (!hasNext()) { throw new NoSuchElementException(); } InstructionHandle result = next; next = (result == last) ? null : next.getNext(); return result; }
/** * Get the successor of given instruction within the basic block. * * @param handle * the instruction * @return the instruction's successor, or null if the instruction is the * last in the basic block */ public @CheckForNull InstructionHandle getSuccessorOf(InstructionHandle handle) { if (VERIFY_INTEGRITY) { if (!containsInstruction(handle)) { throw new IllegalStateException(); } } return handle == lastInstruction ? null : handle.getNext(); }
@Override public void visitIfInstruction(IfInstruction ins) { isBranch = true; InstructionHandle target = ins.getTarget(); if (target == null) { throw new IllegalStateException(); } targetList.add(new Target(target, IFCMP_EDGE)); InstructionHandle fallThrough = handle.getNext(); targetList.add(new Target(fallThrough, FALL_THROUGH_EDGE)); }
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; } } }
/** * Determines whether this outlineable {@link MethodGenerator.Chunk} is * followed immediately by the argument * <code>MethodGenerator.Chunk</code>, with no other intervening * instructions, including {@link OutlineableChunkStart} or * {@link OutlineableChunkEnd} instructions. * @param neighbour an outlineable {@link MethodGenerator.Chunk} * @return <code>true</code> if and only if the argument chunk * immediately follows <code>this</code> chunk */ boolean isAdjacentTo(Chunk neighbour) { return getChunkEnd().getNext() == neighbour.getChunkStart(); }
public static boolean isThrower(BasicBlock target) { InstructionHandle ins = target.getFirstInstruction(); int maxCount = 7; while (ins != null) { if (maxCount-- <= 0) { break; } Instruction i = ins.getInstruction(); if (i instanceof ATHROW) { return true; } if (i instanceof InstructionTargeter || i instanceof ReturnInstruction) { return false; } ins = ins.getNext(); } return false; }
public static boolean isThrower(BasicBlock target) { InstructionHandle ins = target.getFirstInstruction(); int maxCount = 7; while (ins != null) { if (maxCount-- <= 0) { break; } Instruction i = ins.getInstruction(); if (i instanceof ATHROW) { return true; } if (i instanceof InstructionTargeter || i instanceof ReturnInstruction) { return false; } ins = ins.getNext(); } return false; }
private static boolean check(InstructionHandle h, int[] opcodes) { for (int opcode : opcodes) { if (h == null) { return false; } short opcode2 = h.getInstruction().getOpcode(); if (opcode == Const.LDC) { switch (opcode2) { case Const.LDC: case Const.ALOAD: case Const.ALOAD_0: case Const.ALOAD_1: case Const.ALOAD_2: case Const.ALOAD_3: break; default: return false; } } else if (opcode2 != opcode) { return false; } h = h.getNext(); } return true; }
public static boolean isNullCheck(InstructionHandle h, ConstantPoolGen cpg) { if (!(h.getInstruction() instanceof IFNONNULL)) { return false; } h = h.getNext(); final Instruction newInstruction = h.getInstruction(); if (!(newInstruction instanceof NEW)) { return false; } final ObjectType loadClassType = ((NEW) newInstruction).getLoadClassType(cpg); if (!"java.lang.NullPointerException".equals(loadClassType.getClassName())) { return false; } h = h.getNext(); return check(h, NULLCHECK1) || check(h, NULLCHECK2); }
public boolean isAssertionHandle(InstructionHandle handle, ConstantPoolGen cpg) { Instruction ins = handle.getInstruction(); if (isAssertionInstruction(ins, cpg)) { return true; } if (ins instanceof SIPUSH) { int v = ((SIPUSH) ins).getValue().intValue(); if (v == 500) { Instruction next = handle.getNext().getInstruction(); if (next instanceof INVOKEINTERFACE) { INVOKEINTERFACE iInterface = (INVOKEINTERFACE) next; String className = iInterface.getClassName(cpg); String fieldName = iInterface.getMethodName(cpg); if ("javax.servlet.http.HttpServletResponse".equals(className) && "setStatus".equals(fieldName)) { return true; } } } } return false; }
public boolean preScreen(MethodGen mg) { ConstantPoolGen cpg = mg.getConstantPool(); int lockCount = mg.isSynchronized() ? 1 : 0; boolean sawWaitOrNotify = false; InstructionHandle handle = mg.getInstructionList().getStart(); while (handle != null && !(lockCount >= 2 && sawWaitOrNotify)) { Instruction ins = handle.getInstruction(); if (ins instanceof MONITORENTER) { ++lockCount; } else if (ins instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL inv = (INVOKEVIRTUAL) ins; String methodName = inv.getMethodName(cpg); if ("wait".equals(methodName) || methodName.startsWith("notify")) { sawWaitOrNotify = true; } } handle = handle.getNext(); } return lockCount >= 2 && sawWaitOrNotify; }
public static LocalVariableAnnotation getLocalVariableAnnotation(Method method, Location location, IndexedInstruction ins) { int local = ins.getIndex(); InstructionHandle handle = location.getHandle(); int position1 = handle.getNext().getPosition(); int position2 = handle.getPosition(); return getLocalVariableAnnotation(method, local, position1, position2); }
private InstructionHandle findThenFinish(CFG cfg, BasicBlock thenBB, int elsePos) { InstructionHandle inst = thenBB.getFirstInstruction(); while (inst == null) { Iterator<Edge> ie = cfg.outgoingEdgeIterator(thenBB); while (ie.hasNext()) { Edge e = ie.next(); if (e.getType() == EdgeTypes.FALL_THROUGH_EDGE) { thenBB = e.getTarget(); break; } } inst = thenBB.getFirstInstruction(); } InstructionHandle lastIns = inst; while (inst.getPosition() < elsePos) { lastIns = inst; inst = inst.getNext(); } return lastIns; }
private void analyzeMethod(Method m, ClassContext classContext) throws CFGBuilderException, DataflowAnalysisException { ConstantPoolGen cpg = classContext.getConstantPoolGen(); CFG cfg = classContext.getCFG(m); for (Iterator<Location> i = cfg.locationIterator(); i.hasNext(); ) { Location location = i.next(); Instruction inst = location.getHandle().getInstruction(); if (inst instanceof LDC) { LDC ldc = (LDC) inst; if (ldc != null) { if("java.naming.security.authentication".equals(ldc.getValue(cpg)) && "none".equals(ByteCode.getConstantLDC(location.getHandle().getNext(), cpg, String.class))){ JavaClass clz = classContext.getJavaClass(); bugReporter.reportBug(new BugInstance(this, LDAP_ANONYMOUS, Priorities.LOW_PRIORITY) // .addClass(clz) .addMethod(clz, m) .addSourceLine(classContext, m, location)); break; } } } } }
/** * Translate the "test" expression and contents of this element. * The contents will be ignored if we know the test will always fail. */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final InstructionList il = methodGen.getInstructionList(); _test.translateDesynthesized(classGen, methodGen); // remember end of condition final InstructionHandle truec = il.getEnd(); if (!_ignore) { translateContents(classGen, methodGen); } _test.backPatchFalseList(il.append(NOP)); _test.backPatchTrueList(truec.getNext()); } }
boolean propagateToReturnValue(Set<ValueInfo> vals, ValueNumber vn, GenLocation location, MethodDescriptor m) throws DataflowAnalysisException { for(ValueInfo vi : vals) { if(vi.type.getSignature().startsWith("[") && vi.hasObjectOnlyCall && vi.var == null && vn.getNumber() == vi.origValue) { // Ignore initialized arrays passed to methods vi.escaped = true; count--; } } if (Type.getReturnType(m.getSignature()) == Type.VOID || location instanceof ExceptionLocation) { return false; } InstructionHandle nextHandle = location.getHandle().getNext(); if (nextHandle == null || (nextHandle.getInstruction() instanceof POP || nextHandle.getInstruction() instanceof POP2)) { return false; } return propagateValues(vals, null, location.frameAfter().getTopValue()); }
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final InstructionList il = methodGen.getInstructionList(); _left.translate(classGen, methodGen); final InstructionHandle gotot = il.append(new GOTO(null)); il.append(methodGen.loadContextNode()); _right.translate(classGen, methodGen); _left._trueList.backPatch(gotot); _left._falseList.backPatch(gotot.getNext()); _trueList.append(_right._trueList.add(gotot)); _falseList.append(_right._falseList); } }
/** * Get the dataflow fact representing the point just after given Location. * Note "after" is meant in the logical sense, so for backward analyses, * after means before the location in the control flow sense. * * @param location * the location * @return the fact at the point just after the location */ @Override public Fact getFactAfterLocation(Location location) throws DataflowAnalysisException { BasicBlock basicBlock = location.getBasicBlock(); InstructionHandle handle = location.getHandle(); if (handle == (isForwards() ? basicBlock.getLastInstruction() : basicBlock.getFirstInstruction())) { return getResultFact(basicBlock); } else { return getFactAtLocation(new Location(isForwards() ? handle.getNext() : handle.getPrev(), basicBlock)); } }
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(); } }