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