1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.generic;
18
19 import java.io.DataOutputStream;
20 import java.io.IOException;
21 import org.apache.bcel.classfile.Constant;
22 import org.apache.bcel.classfile.ConstantClass;
23 import org.apache.bcel.classfile.ConstantPool;
24 import org.apache.bcel.util.ByteSequence;
25
26 /***
27 * Abstract super class for instructions that use an index into the
28 * constant pool such as LDC, INVOKEVIRTUAL, etc.
29 *
30 * @see ConstantPoolGen
31 * @see LDC
32 * @see INVOKEVIRTUAL
33 *
34 * @version $Id: CPInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
35 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
36 */
37 public abstract class CPInstruction extends Instruction implements TypedInstruction,
38 IndexedInstruction {
39
40 protected int index;
41
42
43 /***
44 * Empty constructor needed for the Class.newInstance() statement in
45 * Instruction.readInstruction(). Not to be used otherwise.
46 */
47 CPInstruction() {
48 }
49
50
51 /***
52 * @param index to constant pool
53 */
54 protected CPInstruction(short opcode, int index) {
55 super(opcode, (short) 3);
56 setIndex(index);
57 }
58
59
60 /***
61 * Dump instruction as byte code to stream out.
62 * @param out Output stream
63 */
64 public void dump( DataOutputStream out ) throws IOException {
65 out.writeByte(opcode);
66 out.writeShort(index);
67 }
68
69
70 /***
71 * Long output format:
72 *
73 * <name of opcode> "["<opcode number>"]"
74 * "("<length of instruction>")" "<"< constant pool index>">"
75 *
76 * @param verbose long/short format switch
77 * @return mnemonic for instruction
78 */
79 public String toString( boolean verbose ) {
80 return super.toString(verbose) + " " + index;
81 }
82
83
84 /***
85 * @return mnemonic for instruction with symbolic references resolved
86 */
87 public String toString( ConstantPool cp ) {
88 Constant c = cp.getConstant(index);
89 String str = cp.constantToString(c);
90 if (c instanceof ConstantClass) {
91 str = str.replace('.', '/');
92 }
93 return org.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + str;
94 }
95
96
97 /***
98 * Read needed data (i.e., index) from file.
99 * @param bytes input stream
100 * @param wide wide prefix?
101 */
102 protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
103 setIndex(bytes.readUnsignedShort());
104 length = 3;
105 }
106
107
108 /***
109 * @return index in constant pool referred by this instruction.
110 */
111 public final int getIndex() {
112 return index;
113 }
114
115
116 /***
117 * Set the index to constant pool.
118 * @param index in constant pool.
119 */
120 public void setIndex( int index ) {
121 if (index < 0) {
122 throw new ClassGenException("Negative index value: " + index);
123 }
124 this.index = index;
125 }
126
127
128 /*** @return type related with this instruction.
129 */
130 public Type getType( ConstantPoolGen cpg ) {
131 ConstantPool cp = cpg.getConstantPool();
132 String name = cp.getConstantString(index, org.apache.bcel.Constants.CONSTANT_Class);
133 if (!name.startsWith("[")) {
134 name = "L" + name + ";";
135 }
136 return Type.getType(name);
137 }
138 }