View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.bcel.generic;
18  
19  import java.io.DataOutputStream;
20  import java.io.IOException;
21  
22  import org.apache.bcel.classfile.Constant;
23  import org.apache.bcel.classfile.ConstantClass;
24  import org.apache.bcel.classfile.ConstantPool;
25  import org.apache.bcel.classfile.Utility;
26  import org.apache.bcel.util.ByteSequence;
27  
28  /**
29   * Abstract super class for instructions that use an index into the constant pool such as LDC, INVOKEVIRTUAL, etc.
30   *
31   * @see ConstantPoolGen
32   * @see LDC
33   * @see INVOKEVIRTUAL
34   */
35  public abstract class CPInstruction extends Instruction implements TypedInstruction, IndexedInstruction {
36  
37      /**
38       * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
39       */
40      @Deprecated
41      protected int index; // index to constant pool
42  
43      /**
44       * Empty constructor needed for Instruction.readInstruction. Not to be used otherwise.
45       */
46      CPInstruction() {
47      }
48  
49      /**
50       * @param index to constant pool
51       */
52      protected CPInstruction(final short opcode, final int index) {
53          super(opcode, (short) 3);
54          setIndex(index);
55      }
56  
57      /**
58       * Dump instruction as byte code to stream out.
59       *
60       * @param out Output stream
61       */
62      @Override
63      public void dump(final DataOutputStream out) throws IOException {
64          out.writeByte(super.getOpcode());
65          out.writeShort(index);
66      }
67  
68      /**
69       * @return index in constant pool referred by this instruction.
70       */
71      @Override
72      public final int getIndex() {
73          return index;
74      }
75  
76      /**
77       * @return type related with this instruction.
78       */
79      @Override
80      public Type getType(final ConstantPoolGen cpg) {
81          final ConstantPool cp = cpg.getConstantPool();
82          String name = cp.getConstantString(index, org.apache.bcel.Const.CONSTANT_Class);
83          if (!name.startsWith("[")) {
84              name = "L" + name + ";";
85          }
86          return Type.getType(name);
87      }
88  
89      /**
90       * Read needed data (i.e., index) from file.
91       *
92       * @param bytes input stream
93       * @param wide wide prefix?
94       */
95      @Override
96      protected void initFromFile(final ByteSequence bytes, final boolean wide) throws IOException {
97          setIndex(bytes.readUnsignedShort());
98          super.setLength(3);
99      }
100 
101     /**
102      * Sets the index to constant pool.
103      *
104      * @param index in constant pool.
105      */
106     @Override
107     public void setIndex(final int index) { // TODO could be package-protected?
108         if (index < 0) {
109             throw new ClassGenException("Negative index value: " + index);
110         }
111         this.index = index;
112     }
113 
114     /**
115      * Long output format:
116      *
117      * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" "("&lt;length of instruction&gt;")" "&lt;"&lt; constant pool
118      * index&gt;"&gt;"
119      *
120      * @param verbose long/short format switch
121      * @return mnemonic for instruction
122      */
123     @Override
124     public String toString(final boolean verbose) {
125         return super.toString(verbose) + " " + index;
126     }
127 
128     /**
129      * @return mnemonic for instruction with symbolic references resolved
130      */
131     @Override
132     public String toString(final ConstantPool cp) {
133         final Constant c = cp.getConstant(index);
134         String str = cp.constantToString(c);
135         if (c instanceof ConstantClass) {
136             str = Utility.packageToPath(str);
137         }
138         return org.apache.bcel.Const.getOpcodeName(super.getOpcode()) + " " + str;
139     }
140 }