1 19 20 package edu.umd.cs.findbugs.ba; 21 22 import org.apache.bcel.generic.ARETURN; 23 import org.apache.bcel.generic.ConstantPoolGen; 24 import org.apache.bcel.generic.FieldInstruction; 25 import org.apache.bcel.generic.INVOKEINTERFACE; 26 import org.apache.bcel.generic.INVOKESPECIAL; 27 import org.apache.bcel.generic.INVOKESTATIC; 28 import org.apache.bcel.generic.INVOKEVIRTUAL; 29 import org.apache.bcel.generic.InstructionHandle; 30 import org.apache.bcel.generic.InvokeInstruction; 31 import org.apache.bcel.generic.PUTFIELD; 32 import org.apache.bcel.generic.PUTSTATIC; 33 34 public abstract class ResourceValueFrameModelingVisitor extends AbstractFrameModelingVisitor<ResourceValue, ResourceValueFrame> { 35 public ResourceValueFrameModelingVisitor(ConstantPoolGen cpg) { 36 super(cpg); 37 } 38 39 @Override 40 public ResourceValue getDefaultValue() { 41 return ResourceValue.notInstance(); 42 } 43 44 48 public abstract void transferInstruction(InstructionHandle handle, BasicBlock basicBlock) throws DataflowAnalysisException; 49 50 56 private void handleFieldStore(FieldInstruction ins) { 57 try { 58 ResourceValueFrame frame = getFrame(); 60 ResourceValue topValue = frame.getTopValue(); 61 if (topValue.equals(ResourceValue.instance())) 62 frame.setStatus(ResourceValueFrame.ESCAPED); 63 } catch (DataflowAnalysisException e) { 64 throw new InvalidBytecodeException("Stack underflow", e); 65 } 66 67 handleNormalInstruction(ins); 68 } 69 70 @Override 71 public void visitPUTFIELD(PUTFIELD putfield) { 72 handleFieldStore(putfield); 73 } 74 75 @Override 76 public void visitPUTSTATIC(PUTSTATIC putstatic) { 77 handleFieldStore(putstatic); 78 } 79 80 89 protected boolean instanceEscapes(InvokeInstruction inv, int instanceArgNum) { 90 return true; 91 } 92 93 private void handleInvoke(InvokeInstruction inv) { 94 ResourceValueFrame frame = getFrame(); 95 int numSlots = frame.getNumSlots(); 96 int numConsumed = getNumWordsConsumed(inv); 97 98 int instanceArgNum = -1; 100 for (int i = numSlots - numConsumed, argCount = 0; i < numSlots; ++i, ++argCount) { 101 ResourceValue value = frame.getValue(i); 102 if (value.equals(ResourceValue.instance())) { 103 instanceArgNum = argCount; 104 break; 105 } 106 } 107 108 if (instanceArgNum >= 0 && instanceEscapes(inv, instanceArgNum)) 109 frame.setStatus(ResourceValueFrame.ESCAPED); 110 111 handleNormalInstruction(inv); 112 } 113 114 @Override 115 public void visitINVOKEVIRTUAL(INVOKEVIRTUAL inv) { 116 handleInvoke(inv); 117 } 118 119 @Override 120 public void visitINVOKEINTERFACE(INVOKEINTERFACE inv) { 121 handleInvoke(inv); 122 } 123 124 @Override 125 public void visitINVOKESPECIAL(INVOKESPECIAL inv) { 126 handleInvoke(inv); 127 } 128 129 @Override 130 public void visitINVOKESTATIC(INVOKESTATIC inv) { 131 handleInvoke(inv); 132 } 133 134 @Override 135 public void visitARETURN(ARETURN ins) { 136 try { 137 ResourceValueFrame frame = getFrame(); 138 ResourceValue topValue = frame.getTopValue(); 139 if (topValue.equals(ResourceValue.instance())) 140 frame.setStatus(ResourceValueFrame.ESCAPED); 141 } catch (DataflowAnalysisException e) { 142 throw new InvalidBytecodeException("Stack underflow", e); 143 } 144 145 handleNormalInstruction(ins); 146 } 147 148 } 149 150 | Popular Tags |