Home | History | Annotate | Download | only in generic
      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$
     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 }
    151