KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > ResourceValueFrameModelingVisitor


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003,2004 University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

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 JavaDoc
40          public ResourceValue getDefaultValue() {
41         return ResourceValue.notInstance();
42     }
43
44     /**
45      * Subclasses must override this to model the effect of the
46      * given instruction on the current frame.
47      */

48     public abstract void transferInstruction(InstructionHandle handle, BasicBlock basicBlock) throws DataflowAnalysisException;
49
50     // Things to do:
51
// Automatically detect when resource instances escape:
52
// - putfield, putstatic
53
// - parameters to invoke, but subclasses may override
54
// - return (areturn)
55

56     private void handleFieldStore(FieldInstruction ins) {
57         try {
58             // If the resource instance is stored in a field, then it escapes
59
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 JavaDoc
71          public void visitPUTFIELD(PUTFIELD putfield) {
72         handleFieldStore(putfield);
73     }
74
75     @Override JavaDoc
76          public void visitPUTSTATIC(PUTSTATIC putstatic) {
77         handleFieldStore(putstatic);
78     }
79
80     /**
81      * Override this to check for methods that it is legal to
82      * pass the instance to without the instance escaping.
83      * By default, we consider all methods to be possible escape routes.
84      *
85      * @param inv the InvokeInstruction to which the resource instance
86      * is passed as an argument
87      * @param instanceArgNum the first argument the instance is passed in
88      */

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         // See if the resource instance is passed as an argument
99
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 JavaDoc
115          public void visitINVOKEVIRTUAL(INVOKEVIRTUAL inv) {
116         handleInvoke(inv);
117     }
118
119     @Override JavaDoc
120          public void visitINVOKEINTERFACE(INVOKEINTERFACE inv) {
121         handleInvoke(inv);
122     }
123
124     @Override JavaDoc
125          public void visitINVOKESPECIAL(INVOKESPECIAL inv) {
126         handleInvoke(inv);
127     }
128
129     @Override JavaDoc
130          public void visitINVOKESTATIC(INVOKESTATIC inv) {
131         handleInvoke(inv);
132     }
133
134     @Override JavaDoc
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 // vim:ts=4
151
Popular Tags