/** * Get the value on the top of the Java operand stack. * * @throws DataflowAnalysisException * if the Java operand stack is empty */ public ValueType getTopValue() throws DataflowAnalysisException { if (!isValid()) { throw new DataflowAnalysisException("accessing top or bottom frame"); } assert slotList.size() >= numLocals; if (slotList.size() == numLocals) { throw new DataflowAnalysisException("operand stack is empty"); } return slotList.get(slotList.size() - 1); }
/** * Pop a value off of the Java operand stack. * * @return the value that was popped * @throws DataflowAnalysisException * if the Java operand stack is empty */ public ValueType popValue() throws DataflowAnalysisException { if (!isValid()) { throw new DataflowAnalysisException("accessing top or bottom frame"); } if (slotList.size() == numLocals) { throw new DataflowAnalysisException("operand stack empty"); } return slotList.remove(slotList.size() - 1); }
/** * @return true if the method can return normally at this location, false * otherwise */ public boolean canReturnNormally() throws DataflowAnalysisException { if (!isValid()) { throw new DataflowAnalysisException("Checking invalid ReturnPathType"); } return type == CAN_RETURN_NORMALLY; }
/** * Get a the location in the frame of a value on the operand stack. * * @param loc * the stack location, counting downwards from the top (location * 0) */ public int getStackLocation(int loc) throws DataflowAnalysisException { int stackDepth = getStackDepth(); if (loc >= stackDepth) { throw new DataflowAnalysisException("not enough values on stack: access=" + loc + ", avail=" + stackDepth); } return slotList.size() - (loc + 1); }
/** * Get the values on the top of the Java operand stack. The top stack item * is placed at the end of the array, so that to restore the values to the * stack, you would push them in the order they appear in the array. */ public void getTopStackWords(ValueType[] valueList) throws DataflowAnalysisException { int stackDepth = getStackDepth(); if (valueList.length > stackDepth) { throw new DataflowAnalysisException("not enough values on stack"); } int numSlots = slotList.size(); for (int i = numSlots - valueList.length, j = 0; i < numSlots; ++i, ++j) { valueList[j] = slotList.get(i); } }
/** * Get a value on the operand stack. * * @param loc * the stack location, counting downwards from the top (location * 0) */ public ValueType getStackValue(int loc) throws DataflowAnalysisException { if (!isValid()) { throw new DataflowAnalysisException("Accessing TOP or BOTTOM frame!"); } int stackDepth = getStackDepth(); if (loc >= stackDepth) { throw new DataflowAnalysisException("not enough values on stack: access=" + loc + ", avail=" + stackDepth); } if (loc < 0) { throw new DataflowAnalysisException("can't get position " + loc + " of stack"); } int pos = slotList.size() - (loc + 1); return slotList.get(pos); }
/** * Get the number of arguments passed to given method invocation, including * the object instance if the call is to an instance method. * * @param ins * the method invocation instruction * @param cpg * the ConstantPoolGen for the class containing the method * @return number of arguments, including object instance if appropriate * @throws DataflowAnalysisException */ public int getNumArgumentsIncludingObjectInstance(InvokeInstruction ins, ConstantPoolGen cpg) throws DataflowAnalysisException { int numConsumed = ins.consumeStack(cpg); if (numConsumed == Const.UNPREDICTABLE) { throw new DataflowAnalysisException("Unpredictable stack consumption in " + ins); } return numConsumed; }
/** * Get the stack location (counting down from top of stack, starting at 0) * containing the object instance referred to by given instruction. This * relies on the observation that in instructions which use an object * instance (such as getfield, invokevirtual, etc.), the object instance is * the first operand used by the instruction. * * <p> * The value returned may be passed to getStackValue(int). * </p> * * @param ins * the Instruction * @param cpg * the ConstantPoolGen for the method * @return stack location (counting down from top of stack, starting at 0) * containing the object instance * @throws DataflowAnalysisException */ public int getInstanceStackLocation(Instruction ins, ConstantPoolGen cpg) throws DataflowAnalysisException { int numConsumed = ins.consumeStack(cpg); if (numConsumed == Const.UNPREDICTABLE) { throw new DataflowAnalysisException("Unpredictable stack consumption in " + ins); } return numConsumed - 1; }
/** * Get the slot the object instance referred to by given instruction is * located in. * * @param ins * the Instruction * @param cpg * the ConstantPoolGen for the method * @return stack slot the object instance is in * @throws DataflowAnalysisException */ public int getInstanceSlot(Instruction ins, ConstantPoolGen cpg) throws DataflowAnalysisException { if (!isValid()) { throw new DataflowAnalysisException("Accessing invalid frame at " + ins); } int numConsumed = ins.consumeStack(cpg); if (numConsumed == Const.UNPREDICTABLE) { throw new DataflowAnalysisException("Unpredictable stack consumption in " + ins); } if (numConsumed > getStackDepth()) { throw new DataflowAnalysisException("Stack underflow " + ins); } return getNumSlots() - numConsumed; }
/** * Get the <i>i</i>th operand used by given instruction. * * @param ins * the instruction, which must be a StackConsumer * @param cpg * the ConstantPoolGen * @param i * index of operand to get: 0 for the first operand, etc. * @return the <i>i</i>th operand used by the given instruction * @throws DataflowAnalysisException */ public ValueType getOperand(StackConsumer ins, ConstantPoolGen cpg, int i) throws DataflowAnalysisException { int numOperands = ins.consumeStack(cpg); if (numOperands == Const.UNPREDICTABLE) { throw new DataflowAnalysisException("Unpredictable stack consumption in " + ins); } return getStackValue((numOperands - 1) - i); }
/** * Analyze the given Instruction. * * @param ins * the Instruction * @throws DataflowAnalysisException * if an error occurs analyzing the instruction; in most cases, * this indicates that the bytecode for the method being * analyzed is invalid */ public void analyzeInstruction(Instruction ins) throws DataflowAnalysisException { if (frame.isValid()) { try { ins.accept(this); } catch (InvalidBytecodeException e) { String message = "Invalid bytecode: could not analyze instr. " + ins + " at frame " + frame; throw new DataflowAnalysisException(message, e); } } }
public void mergeWith(TypeQualifierValueSet fact) throws DataflowAnalysisException { if (!isValid() || !fact.isValid()) { throw new DataflowAnalysisException("merging an invalid TypeQualifierValueSet"); } Set<ValueNumber> interesting = new HashSet<>(); interesting.addAll(this.valueMap.keySet()); interesting.addAll(fact.valueMap.keySet()); for (ValueNumber vn : interesting) { setValue(vn, FlowValue.meet(this.getValue(vn), fact.getValue(vn))); mergeSourceSinkInfoSets(this.whereAlways, fact.whereAlways, vn); mergeSourceSinkInfoSets(this.whereNever, fact.whereNever, vn); } }
throw new DataflowAnalysisException("Stack underflow at " + lastHandle);
assert methodGen != null; if (numConsumed == Const.UNPREDICTABLE) { throw new DataflowAnalysisException("Unpredictable stack consumption", methodGen, handle);
throw new DataflowAnalysisException("Too many iterations (" + numIterations + ") in dataflow when analyzing " + getFullyQualifiedMethodName());
int numConsumed = inv.consumeStack(cpg); if (numConsumed == Const.UNPREDICTABLE) { throw new DataflowAnalysisException("Unpredictable stack consumption", methodGen, handle); throw new DataflowAnalysisException("Stack underflow", methodGen, handle);
throw new DataflowAnalysisException("Stack underflow", methodGen, handle);
throw new DataflowAnalysisException("Field accessed through non-object reference " + instanceType, methodGen, handle);
throw new DataflowAnalysisException("Unpredictable stack production", methodGen, handle);
throw new DataflowAnalysisException("Stack underflow", methodGen, handle);