KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > coffi > Instruction


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

19
20 /*
21  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26
27
28
29
30
31
32 package soot.coffi;
33 import java.io.*;
34 /** Instruction subclasses are used to represent parsed bytecode; each
35  * bytecode operation has a corresponding subclass of Instruction.
36  * <p>
37  * Each subclass is derived from one of
38  * <ul><li>Instruction</li>
39  * <li>Instruction_noargs (an Instruction with no embedded arguments)</li>
40  * <li>Instruction_byte (an Instruction with a single byte data argument)</li>
41  * <li>Instruction_bytevar (a byte argument specifying a local variable)</li>
42  * <li>Instruction_byteindex (a byte argument specifying a constant pool index)</li>
43  * <li>Instruction_int (an Instruction with a single short data argument)</li>
44  * <li>Instruction_intvar (a short argument specifying a local variable)</li>
45  * <li>Instruction_intindex (a short argument specifying a constant pool index)</li>
46  * <li>Instruction_intbranch (a short argument specifying a code offset)</li>
47  * <li>Instruction_longbranch (an int argument specifying a code offset)</li>
48  * </ul>
49  * @author Clark Verbrugge
50  * @see Instruction
51  * @see Instruction_noargs
52  * @see Instruction_byte
53  * @see Instruction_bytevar
54  * @see Instruction_byteindex
55  * @see Instruction_int
56  * @see Instruction_intvar
57  * @see Instruction_intindex
58  * @see Instruction_intbranch
59  * @see Instruction_longbranch
60  * @see Instruction_Unknown
61  */

62  abstract class Instruction implements Cloneable JavaDoc {
63
64    /** String used to separate arguments in printing. */
65    public static final String JavaDoc argsep = " ";
66    /** String used to construct names for local variables. */
67    public static final String JavaDoc LOCALPREFIX = "local_";
68    // public static int w; // set by the wide instr. and used by other instrs
69

70    /** Actual byte code of this instruction. */
71    public byte code;
72    /** Offset of this instruction from the start of code.
73     * @see ClassFile#relabel
74     */

75    public int label;
76    /** Name of this instruction.
77     * @see Instruction#toString
78     */

79    public String JavaDoc name;
80
81    /** Reference for chaining. */
82    public Instruction next;
83    /** More convenient for chaining. */
84    public Instruction prev;
85    /** Whether this instruction is the target of a branch. */
86    public boolean labelled;
87    /** Whether this instruction branches. */
88    public boolean branches;
89    /** Whether this instruction is a method invocation. */
90    public boolean calls;
91    /** Whether this instruction is a return. */
92    public boolean returns;
93
94      /** Successor array. It is different from the field 'next'. */
95      public Instruction[] succs;
96
97    int originalIndex;
98
99    /** Constructs a new Instruction for this bytecode.
100     * @param c bytecode of the instruction.
101     */

102    public Instruction(byte c) {
103       code = c;
104       next = null;
105       branches = false;
106       calls = false;
107       returns = false;
108    }
109
110    protected Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
111
112     return super.clone();
113
114    }
115
116
117    public String JavaDoc toString()
118    {
119       return label +": "+name + "[" + originalIndex + "]";
120    }
121
122    /** Assuming the actual bytecode for this instruction has been extracted already,
123     * and index is the offset of the next byte, this method parses whatever
124     * arguments the instruction requires and return the offset of the next
125     * available byte.
126     * @param bc complete array of bytecode.
127     * @param index offset of remaining bytecode after this instruction's
128     * bytecode was parsed.
129     * @return offset of the next available bytecode.
130     * @see ByteCode#disassemble_bytecode
131     * @see Instruction#compile
132     */

133    public abstract int parse(byte bc[],int index);
134
135    /** Writes out the sequence of bytecodes represented by this instruction, including
136     * any arguments.
137     * @param bc complete array of bytecode.
138     * @param index offset of remaining bytecode at which to start writing.
139     * @return offset of the next available bytecode.
140     * @see ClassFile#unparseMethod
141     * @see Instruction#parse
142     */

143    public abstract int compile(byte bc[],int index);
144
145    /** Changes offset values in this instruction to Instruction references;
146     * default behaviour is to do nothing.
147     * @param bc complete array of bytecode.
148     * @see ByteCode#build
149     */

150    public void offsetToPointer(ByteCode bc) { }
151
152
153    /** Returns the next available offset assuming this instruction begins
154     * on the indicated offset; default assumes no arguments.
155     * @param curr offset this instruction would be on.
156     * @return next available offset.
157     * @see ClassFile#relabel
158     */

159    public int nextOffset(int curr) { return curr+1; }
160
161    /** Returns an array of the instructions to which this instruction
162     * might branch (only valid if branches==<i>true</i>; default action is
163     * to return <i>null</i>).
164     * @param next the instruction following this one, in case of default flow through.
165     * @return array of instructions which may be targets of this instruction.
166     * @see Instruction#branches
167     */

168     public Instruction[] branchpoints(Instruction next)
169     {
170         /*
171         Instruction[] bps= new Instruction[1];
172         bps[0] = next;
173         return bps;
174         */

175         return null;
176     }
177
178    /** Marks the appropriate spot if that constant_pool entry is used by this instr.
179     * For every constant pool entry used (referenced) by this instruction, the
180     * corresponding boolean in the given array is set to <i>true</i>.
181     * @param refs array of booleans the same size as the constant pool array.
182     * @see ClassFile#constant_pool
183     */

184    public void markCPRefs(boolean[] refs) { }
185
186    /** Updates all constant pool references within this instruction to use
187     * new indices, based on the given redirection array.
188     * @param redirect array of new indices of constant pool entries.
189     * @see ClassFile#constant_pool
190     */

191    public void redirectCPRefs(short redirect[]) { }
192
193    /** For storing in a Hashtable.
194     * @return unique hash code for this instruction, assuming labels are unique.
195     */

196    public int hashCode() {
197       return (new Integer JavaDoc(label)).hashCode();
198    }
199
200    /** For storing in a Hashtable.
201     * @param i the Instruction to which this is compared.
202     * @return <i>true</i> if <i>i</i> is the same, <i>false</i> otherwise.
203     */

204    public boolean equals(Instruction i) {
205        return (this == i);
206        /*
207       if (label == i.label) return true;
208       return false;
209        */

210    }
211
212    /** Utility routines, used mostly by the parse routines of various
213     * Instruction subclasses;
214     * this method converts two bytes into a short.
215     * @param bc complete array of bytecode.
216     * @param index offset of data in bc.
217     * @return the short constructed from the two bytes.
218     * @see Instruction#parse
219     * @see Instruction#shortToBytes
220     */

221    public static short getShort(byte bc[],int index) {
222       short s,bh,bl;
223       bh = (short)(bc[index]); bl = (short)(bc[index+1]);
224       s = (short)(((bh<<8)&0xff00) | (bl&0xff));
225       //s = (short)((int)(bc[index])<<8 + bc[index+1]);
226
return s;
227    }
228    /** Utility routines, used mostly by the parse routines of various
229     * Instruction subclasses;
230     * this method converts four bytes into an int.
231     * @param bc complete array of bytecode.
232     * @param index offset of data in bc.
233     * @return the int constructed from the four bytes.
234     * @see Instruction#parse
235     * @see Instruction#intToBytes
236     */

237    public static int getInt(byte bc[],int index) {
238       int i,bhh,bhl,blh,bll;
239       bhh = (((int)(bc[index]))<<24)&0xff000000;
240       bhl = (((int)(bc[index+1]))<<16)&0xff0000;
241       blh = (((int)(bc[index+2]))<<8)&0xff00;
242       bll = ((int)(bc[index+3]))&0xff;
243       i = bhh | bhl | blh | bll;
244       return i;
245    }
246
247    /** Utility routines, used mostly by the compile routines of various
248     * Instruction subclasses;
249     * this method converts a short into two bytes.
250     * @param bc complete array of bytecode in which to store the short.
251     * @param index next available offset in bc.
252     * @return the next available offset in bc
253     * @see Instruction#compile
254     * @see Instruction#getShort
255     */

256    public static int shortToBytes(short s,byte bc[],int index) {
257       bc[index++] = (byte)((s>>8)&0xff);
258       bc[index++] = (byte)(s&0xff);
259       return index;
260    }
261
262    /** Utility routines, used mostly by the compile routines of various
263     * Instruction subclasses;
264     * this method converts an int into four bytes.
265     * @param bc complete array of bytecode in which to store the int.
266     * @param index next available offset in bc.
267     * @return the next available offset in bc
268     * @see Instruction#compile
269     * @see Instruction#getInt
270     */

271    public static int intToBytes(int s,byte bc[],int index) {
272       bc[index++] = (byte)((s>>24)&0xff);
273       bc[index++] = (byte)((s>>16)&0xff);
274       bc[index++] = (byte)((s>>8)&0xff);
275       bc[index++] = (byte)(s&0xff);
276       return index;
277    }
278
279    /** For displaying instructions.
280     * @param constant_pool constant pool of associated ClassFile
281     * @return String representation of this instruction.
282     */

283    public String JavaDoc toString(cp_info constant_pool[]) {
284       int i = ((int)code)&0xff;
285       if (name==null) name = "null???=" + Integer.toString(i);
286       return name;
287    }
288 }
289
Popular Tags