/** * Get the number of words produced by given instruction. */ public int getNumWordsProduced(Instruction ins) { int numWordsProduced = ins.produceStack(cpg); if (numWordsProduced == Const.UNPREDICTABLE) { throw new InvalidBytecodeException("Unpredictable stack productions"); } return numWordsProduced; }
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); } }
@Override public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, StackDepth fact) throws DataflowAnalysisException { Instruction ins = handle.getInstruction(); int produced = ins.produceStack(cpg); int consumed = ins.consumeStack(cpg); if (produced == Const.UNPREDICTABLE || consumed == Const.UNPREDICTABLE) { throw new IllegalStateException("Unpredictable stack delta for instruction: " + handle); } int depth = fact.getDepth(); depth += (produced - consumed); if (depth < 0) { fact.setDepth(BOTTOM); } else { fact.setDepth(depth); } }
private Location getValueNumberCreationLocation(ValueNumberDataflow vnd, ValueNumber vn) { ConstantPoolGen cpg = vnd.getCFG().getMethodGen().getConstantPool(); for(Iterator<Location> it = vnd.getCFG().locationIterator(); it.hasNext(); ) { Location loc = it.next(); if(loc.getHandle().getInstruction().produceStack(cpg) != 1) { continue; } try { ValueNumberFrame vnf = vnd.getFactAfterLocation(loc); if(vnf.getTopValue().equals(vn)) { return loc; } } catch (DataflowAnalysisException e) { AnalysisContext.logError("While analyzing "+vnd.getCFG().getMethodGen()+" at "+loc, e); } } return null; }
private void registerInstructionSources() throws DataflowAnalysisException { for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction instruction = location.getHandle().getInstruction(); short opcode = instruction.getOpcode(); int produces = instruction.produceStack(cpg); if (instruction instanceof InvokeInstruction) { // Model return value registerReturnValueSource(location); } else if (opcode == Const.GETFIELD || opcode == Const.GETSTATIC) { // Model field loads registerFieldLoadSource(location); } else if (instruction instanceof LDC) { // Model constant values registerLDCValueSource(location); } else if (instruction instanceof LDC2_W) { // Model constant values registerLDC2ValueSource(location); } else if (instruction instanceof ConstantPushInstruction) { // Model constant values registerConstantPushSource(location); } else if (instruction instanceof ACONST_NULL) { // Model constant values registerPushNullSource(location); } else if ((produces == 1 || produces == 2) && !(instruction instanceof LocalVariableInstruction) && !(instruction instanceof CHECKCAST)){ // Model other sources registerOtherSource(location); } } }
/** * @param methodGen method * @param start instruction to scan * @return instruction which consumes value which was on top of stack before start instruction * or null if cannot be determined */ private InstructionHandle getConsumer(MethodGen methodGen, InstructionHandle start) { int depth = 1; InstructionHandle cur = start; while(cur != null) { Instruction inst = cur.getInstruction(); depth -= inst.consumeStack(methodGen.getConstantPool()); if(depth <= 0) { return cur; } depth += inst.produceStack(methodGen.getConstantPool()); if(inst instanceof BranchInstruction) { if(inst instanceof GotoInstruction) { cur = ((GotoInstruction)inst).getTarget(); continue; } if(!(inst instanceof IfInstruction)) { return null; } } cur = cur.getNext(); } return null; }
depth = depth - prevInst.produceStack(cpg) + prevInst.consumeStack(cpg); if(depth < 1) { throw new CFGBuilderException("Invalid stack at "+prev+" when checking "+handle);
int prevPush = 0; if (ihPrev != null) { prevPush = ihPrev.getInstruction().produceStack(methodGen.getConstantPool()); prevPrevPush = ihPrevPrev.getInstruction().produceStack(methodGen.getConstantPool());
int numProduced = ins.produceStack(methodGen.getConstantPool()); if (numProduced == Const.UNPREDICTABLE) { throw new DataflowAnalysisException("Unpredictable stack production", methodGen, handle);
/** * Get the number of words produced by given instruction. */ public int getNumWordsProduced(Instruction ins) { int numWordsProduced = ins.produceStack(cpg); if (numWordsProduced == Constants.UNPREDICTABLE) { throw new InvalidBytecodeException("Unpredictable stack productions"); } return numWordsProduced; }
private void checkConsumedAndProducedValues(Instruction ins, ValueNumber[] consumedValueList, ValueNumber[] producedValueList) { int numConsumed = ins.consumeStack(getCPG()); int numProduced = ins.produceStack(getCPG()); if (numConsumed == Constants.UNPREDICTABLE) { throw new InvalidBytecodeException("Unpredictable stack consumption for " + ins); } if (numProduced == Constants.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); } }
@Override public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, StackDepth fact) throws DataflowAnalysisException { Instruction ins = handle.getInstruction(); int produced = ins.produceStack(cpg); int consumed = ins.consumeStack(cpg); if (produced == Constants.UNPREDICTABLE || consumed == Constants.UNPREDICTABLE) { throw new IllegalStateException("Unpredictable stack delta for instruction: " + handle); } int depth = fact.getDepth(); depth += (produced - consumed); if (depth < 0) { fact.setDepth(BOTTOM); } else { fact.setDepth(depth); } }
/** * @param methodGen method * @param start instruction to scan * @return instruction which consumes value which was on top of stack before start instruction * or null if cannot be determined */ private InstructionHandle getConsumer(MethodGen methodGen, InstructionHandle start) { int depth = 1; InstructionHandle cur = start; while(cur != null) { Instruction inst = cur.getInstruction(); depth -= inst.consumeStack(methodGen.getConstantPool()); if(depth <= 0) { return cur; } depth += inst.produceStack(methodGen.getConstantPool()); if(inst instanceof BranchInstruction) { if(inst instanceof GotoInstruction) { cur = ((GotoInstruction)inst).getTarget(); continue; } if(!(inst instanceof IfInstruction)) { return null; } } cur = cur.getNext(); } return null; }
private void registerInstructionSources() throws DataflowAnalysisException { for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction instruction = location.getHandle().getInstruction(); short opcode = instruction.getOpcode(); int produces = instruction.produceStack(cpg); if (instruction instanceof InvokeInstruction) { // Model return value registerReturnValueSource(location); } else if (opcode == Constants.GETFIELD || opcode == Constants.GETSTATIC) { // Model field loads registerFieldLoadSource(location); } else if (instruction instanceof LDC) { // Model constant values registerLDCValueSource(location); } else if (instruction instanceof LDC2_W) { // Model constant values registerLDC2ValueSource(location); } else if (instruction instanceof ConstantPushInstruction) { // Model constant values registerConstantPushSource(location); } else if (instruction instanceof ACONST_NULL) { // Model constant values registerPushNullSource(location); } else if ((produces == 1 || produces == 2) && !(instruction instanceof LocalVariableInstruction) && !(instruction instanceof CHECKCAST)){ // Model other sources registerOtherSource(location); } } }
/** * Ensures the general preconditions of an instruction that accesses the stack. * This method is here because BCEL has no such superinterface for the stack * accessing instructions; and there are funny unexpected exceptions in the * semantices of the superinterfaces and superclasses provided. * E.g. SWAP is a StackConsumer, but DUP_X1 is not a StackProducer. * Therefore, this method is called by all StackProducer, StackConsumer, * and StackInstruction instances via their visitXXX() method. * Unfortunately, as the superclasses and superinterfaces overlap, some instructions * cause this method to be called two or three times. [TODO: Fix this.] * * @see #visitStackConsumer(StackConsumer o) * @see #visitStackProducer(StackProducer o) * @see #visitStackInstruction(StackInstruction o) */ private void _visitStackAccessor(Instruction o){ int consume = o.consumeStack(cpg); // Stack values are always consumed first; then produced. if (consume > stack().slotsUsed()){ constraintViolated((Instruction) o, "Cannot consume "+consume+" stack slots: only "+stack().slotsUsed()+" slot(s) left on stack!\nStack:\n"+stack()); } int produce = o.produceStack(cpg) - ((Instruction) o).consumeStack(cpg); // Stack values are always consumed first; then produced. if ( produce + stack().slotsUsed() > stack().maxStack() ){ constraintViolated((Instruction) o, "Cannot produce "+produce+" stack slots: only "+(stack().maxStack()-stack().slotsUsed())+" free stack slot(s) left.\nStack:\n"+stack()); } }
/** * Ensures the general preconditions of an instruction that accesses the stack. * This method is here because BCEL has no such superinterface for the stack * accessing instructions; and there are funny unexpected exceptions in the * semantices of the superinterfaces and superclasses provided. * E.g. SWAP is a StackConsumer, but DUP_X1 is not a StackProducer. * Therefore, this method is called by all StackProducer, StackConsumer, * and StackInstruction instances via their visitXXX() method. * Unfortunately, as the superclasses and superinterfaces overlap, some instructions * cause this method to be called two or three times. [TODO: Fix this.] * * @see #visitStackConsumer(StackConsumer o) * @see #visitStackProducer(StackProducer o) * @see #visitStackInstruction(StackInstruction o) */ private void _visitStackAccessor(final Instruction o) { final int consume = o.consumeStack(cpg); // Stack values are always consumed first; then produced. if (consume > stack().slotsUsed()) { constraintViolated(o, "Cannot consume "+consume+" stack slots: only "+stack().slotsUsed()+" slot(s) left on stack!\nStack:\n"+stack()); } final int produce = o.produceStack(cpg) - o.consumeStack(cpg); // Stack values are always consumed first; then produced. if ( produce + stack().slotsUsed() > stack().maxStack() ) { constraintViolated(o, "Cannot produce "+produce+" stack slots: only "+(stack().maxStack()-stack().slotsUsed())+ " free stack slot(s) left.\nStack:\n"+stack()); } }
Instruction instruction = ih.getInstruction(); short opcode = instruction.getOpcode(); int delta = instruction.produceStack(cp) - instruction.consumeStack(cp);
final Instruction instruction = ih.getInstruction(); final short opcode = instruction.getOpcode(); final int delta = instruction.produceStack(cp) - instruction.consumeStack(cp); stackDepth += delta; if (stackDepth > maxStackDepth) {
depth = depth - prevInst.produceStack(cpg) + prevInst.consumeStack(cpg); if(depth < 1) { throw new CFGBuilderException("Invalid stack at "+prev+" when checking "+handle);
int numProduced = ins.produceStack(methodGen.getConstantPool()); if (numProduced == Constants.UNPREDICTABLE) { throw new DataflowAnalysisException("Unpredictable stack production", methodGen, handle);