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   */
18  package org.apache.bcel.generic;
19  
20  import java.io.DataOutputStream;
21  import java.io.IOException;
22  
23  import org.apache.bcel.classfile.Constant;
24  import org.apache.bcel.classfile.ConstantClass;
25  import org.apache.bcel.classfile.ConstantPool;
26  import org.apache.bcel.util.ByteSequence;
27  
28  /**
29   * Abstract super class for instructions that use an index into the
30   * constant pool such as LDC, INVOKEVIRTUAL, etc.
31   *
32   * @see ConstantPoolGen
33   * @see LDC
34   * @see INVOKEVIRTUAL
35   *
36   * @version $Id: CPInstruction.html 1021978 2017-12-09 17:38:21Z ggregory $
37   */
38  public abstract class CPInstruction extends Instruction implements TypedInstruction,
39          IndexedInstruction {
40  
41      /**
42       * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
43       */
44      @Deprecated
45      protected int index; // index to constant pool
46  
47  
48      /**
49       * Empty constructor needed for Instruction.readInstruction.
50       * Not to be used otherwise.
51       */
52      CPInstruction() {
53      }
54  
55  
56      /**
57       * @param index to constant pool
58       */
59      protected CPInstruction(final short opcode, final int index) {
60          super(opcode, (short) 3);
61          setIndex(index);
62      }
63  
64  
65      /**
66       * Dump instruction as byte code to stream out.
67       * @param out Output stream
68       */
69      @Override
70      public void dump( final DataOutputStream out ) throws IOException {
71          out.writeByte(super.getOpcode());
72          out.writeShort(index);
73      }
74  
75  
76      /**
77       * Long output format:
78       *
79       * <name of opcode> "["<opcode number>"]"
80       * "("<length of instruction>")" "<"< constant pool index>">"
81       *
82       * @param verbose long/short format switch
83       * @return mnemonic for instruction
84       */
85      @Override
86      public String toString( final boolean verbose ) {
87          return super.toString(verbose) + " " + index;
88      }
89  
90  
91      /**
92       * @return mnemonic for instruction with symbolic references resolved
93       */
94      @Override
95      public String toString( final ConstantPool cp ) {
96          final Constant c = cp.getConstant(index);
97          String str = cp.constantToString(c);
98          if (c instanceof ConstantClass) {
99              str = str.replace('.', '/');
100         }
101         return org.apache.bcel.Const.getOpcodeName(super.getOpcode()) + " " + str;
102     }
103 
104 
105     /**
106      * Read needed data (i.e., index) from file.
107      * @param bytes input stream
108      * @param wide wide prefix?
109      */
110     @Override
111     protected void initFromFile( final ByteSequence bytes, final boolean wide ) throws IOException {
112         setIndex(bytes.readUnsignedShort());
113         super.setLength(3);
114     }
115 
116 
117     /**
118      * @return index in constant pool referred by this instruction.
119      */
120     @Override
121     public final int getIndex() {
122         return index;
123     }
124 
125 
126     /**
127      * Set the index to constant pool.
128      * @param index in  constant pool.
129      */
130     @Override
131     public void setIndex( final int index ) { // TODO could be package-protected?
132         if (index < 0) {
133             throw new ClassGenException("Negative index value: " + index);
134         }
135         this.index = index;
136     }
137 
138 
139     /** @return type related with this instruction.
140      */
141     @Override
142     public Type getType( final ConstantPoolGen cpg ) {
143         final ConstantPool cp = cpg.getConstantPool();
144         String name = cp.getConstantString(index, org.apache.bcel.Const.CONSTANT_Class);
145         if (!name.startsWith("[")) {
146             name = "L" + name + ";";
147         }
148         return Type.getType(name);
149     }
150 }