KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quilt > cl > CodeVertex


1 /* CodeVertex.java */
2 package org.quilt.cl;
3
4 import org.quilt.graph.*;
5 import org.apache.bcel.generic.GotoInstruction;
6 import org.apache.bcel.generic.Instruction;
7 import org.apache.bcel.generic.InstructionHandle;
8 import org.apache.bcel.generic.InstructionList;
9
10 /**
11  * A Vertex extended to carry the initial bytecode offset, line
12  * number, and an instruction list.
13  *
14  * @author <a HREF="mailto:jddixon@users.sourceforge.net">Jim Dixon</a>
15  */

16 public class CodeVertex extends Vertex {
17     /** initial offset of first instruction in bytecode */
18     protected int pos = -1;
19
20     /** the bytecode iteself */
21     protected InstructionList ilist = new InstructionList();
22
23     /**
24      * Line number in source code corresponding to first instruction,
25      * or if there is no such instruction, of the connecting instruction.
26      */

27     protected int startLine_ = -1;
28
29     /**
30      * Line number in source code corresponding to the connecting
31      * instruction, or if there is no such instruction, to the last
32      * instruction in the block
33      */

34     protected int endLine_ = -1;
35
36     /** Instruction connecting this vertex to other(s). */
37     protected Instruction connInst_ = null;
38
39     /**
40      * Create a code vertex with default bytecode offset, line number,
41      * empty instruction list, and no label.
42      *
43      * @param g Graph which the vertex belongs to.
44      */

45     public CodeVertex (ControlFlowGraph g) {
46         super(g);
47     }
48     /** Create a code vertex, specifying a non-negative bytecode offset.
49      *
50      * @param g Graph which the vertex belongs to.
51      * @param position Offset of the first instruction in the bytecode.
52      */

53     public CodeVertex (ControlFlowGraph g, int position) {
54         super(g);
55         if (position < 0) {
56             throw new IllegalArgumentException JavaDoc(
57                     "position cannot be negative");
58         }
59         pos = position;
60     }
61     /**
62      * Create a code vertex, specifying a label
63      *
64      * @param g Graph which the vertex belongs to.
65      * @param l The String label applied to the vertex.
66      */

67     public CodeVertex (ControlFlowGraph g, String JavaDoc l) {
68         super(g);
69         pos = -1;
70         label_ = l;
71     }
72     // GET/SET METHODS //////////////////////////////////////////////
73
/** Get connecting instruction. */
74     public Instruction getConnInst() {
75         return connInst_;
76     }
77     /** Set the connecting instruction for this vertex. */
78     public void setConnInst (Instruction i) {
79         if (i == null) {
80             throw new IllegalArgumentException JavaDoc ("null instruction");
81         }
82         connInst_ = i;
83     }
84 // /** Set the connecting instruction to null. */
85
// public void clearConnInst () {
86
// connInst_ = null;
87
// }
88
/**
89      * Get a reference to the InstructionList carried by the vertex.
90      * This is a doubly indirect reference to the first instruction
91      * in the list.
92      *
93      * @return Instruction list.
94      */

95     public InstructionList getInstructionList() {
96         return ilist;
97     }
98     /**
99      * Get the source code line number of the first instruction in a
100      * code vertex.
101      *
102      * @return Non-negative integer or -1, meaning no line number assigned.
103      */

104     public int getStartLine () {
105         return startLine_;
106     }
107     /**
108      * Set the source code line number.
109      * @param n Source code line number.
110      */

111     public void setStartLine(int n) {
112         startLine_ = n;
113     }
114     /**
115      * Get the line number in source code corresponding to the
116      * connecting instruction or last instruction in the block.
117      */

118     public int getEndLine() {
119         return endLine_;
120     }
121     /**
122      * Set the source line number of the connecting instruction, or of
123      * the last line number in the block if there is no connecting
124      * instruction.
125      *
126      * @param n Source code end line number.
127      */

128     public void setEndLine(int n) {
129         endLine_ = n;
130     }
131     /**
132      * Get the bytecode offset of the first instruction.
133      *
134      * @return The initial bytecode offset of the first instruction
135      * carried by the vertex (excluding any connection instruction.
136      */

137     public int getPosition () {
138         return pos;
139     }
140     /**
141      * Set the bytecode offset for the first instruction.
142      *
143      * XXX Should rename this to <code>setPosition</code> to match the
144      * <code>get</code> method.
145      *
146      * @param position A non-negative integer representing the bytecode
147      * position of the first instruction.
148      */

149     public void setPos (int position) {
150         if (position < 0) {
151             throw new IllegalArgumentException JavaDoc(
152                     "position cannot be negative");
153         }
154         pos = position;
155     }
156     // OTHER METHODS ////////////////////////////////////////////////
157
/**
158      * Move this code vertex's Goto to another code vertex. The
159      * second vertex will be the target on the otherEdge from this
160      * vertex. This vertex has a BinaryConnector. The second vertex
161      * has a UnaryConnector.
162      *
163      * The goto instruction does NOT point to the target. The target
164      * is some sort of instrumentation being inserted into the graph.
165      */

166     public void moveGoto (final CodeVertex target) {
167         if (target == null) {
168             throw new IllegalArgumentException JavaDoc("null target vertex");
169         }
170         // this vertex's binary connector
171
BinaryConnector biConnector = (BinaryConnector)getConnector();
172         Edge flowEdge = biConnector.getEdge();
173         Edge otherEdge = biConnector.getOtherEdge(); // used by goto
174

175         if (otherEdge.getTarget() != target) {
176             throw new IllegalArgumentException JavaDoc("not target of otherEdge");
177         }
178         if (! (connInst_ instanceof GotoInstruction) ) {
179             throw new IllegalArgumentException JavaDoc(
180                                         "connecting instruction not goto");
181         }
182         // the target vertex's unary connector
183
UnaryConnector uConnector = (UnaryConnector)target.getConnector();
184         Edge uEdge = uConnector.getEdge();
185         Vertex tgtTarget = uEdge.getTarget();
186
187 // // DEBUG
188
// System.out.println("CodeVertex.moveGoto:"
189
// + "\n source: " + toString()
190
// + "\n edge: " + flowEdge
191
// + "\n other edge: " + otherEdge
192
// + "\n target: " + target
193
// + "\n edge: " + uEdge
194
// );
195
// // END
196

197         // change the unary connector and move it to this vertex
198
uEdge.setSource(this);
199         uEdge.setTarget(target);
200         setConnector(uConnector);
201
202         // change the binary connector and attach it to the target
203
flowEdge.setSource(target);
204         // flow target is unchanged
205
otherEdge.setSource(target);
206         otherEdge.setTarget(tgtTarget);
207         target.setConnector(biConnector);
208
209         // move the connecting instruction, a goto
210
target.setConnInst (connInst_); // move it to the target
211
connInst_ = null; // erase from this vertex
212

213 // // DEBUG
214
// System.out.println("CodeVertex.moveGoto:"
215
// + "\n source: " + toString()
216
// + "\n edge " + getEdge()
217
// + "\n target: " + target
218
// + "\n edge " + flowEdge
219
// + "\n other edge " + otherEdge );
220
// // END
221
}
222     /**
223      * Less verbose <code>toString.</code>
224      *
225      * @return Graph index and Vertex index in a neatly formatted String,
226      * *not* newline-terminated.
227      */

228     public String JavaDoc toString () {
229         StringBuffer JavaDoc sb = new StringBuffer JavaDoc().append("Code ")
230             .append(super.toString()).append(" pos ") .append(pos);
231
232         // may look a bit strange if there is an end line but no start line
233
if (startLine_ > -1) {
234             sb.append(" line ").append(startLine_);
235         }
236         if (endLine_ > -1) {
237             sb.append("/").append(endLine_);
238         }
239         return sb.toString();
240     }
241     /**
242      * Optionally more verbose method.
243      *
244      * @param b If true, add label (if any) and instruction list.
245      * @return A neatly formatted String.
246      */

247     public String JavaDoc toString (boolean b) {
248         
249         StringBuffer JavaDoc sb = new StringBuffer JavaDoc().append(toString());
250         if (b) {
251             if (label_ != null) {
252                 sb.append ("\n label ") .append(label_);
253             }
254             sb.append("\n ilist: ");
255             InstructionHandle ih = ilist.getStart();
256             while ( ih != null) {
257                 sb.append(ih.getInstruction());
258             }
259         }
260         return sb.toString();
261     }
262 }
263
Popular Tags