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