View Javadoc

1   /*
2    * Copyright  2000-2004 The Apache Software Foundation
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License"); 
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License. 
15   *
16   */
17  package org.apache.bcel.generic;
18  
19  import java.io.DataOutputStream;
20  import java.io.IOException;
21  import org.apache.bcel.util.ByteSequence;
22  
23  /*** 
24   * LDC - Push item from constant pool.
25   *
26   * <PRE>Stack: ... -&gt; ..., item</PRE>
27   *
28   * @version $Id: LDC.java 386056 2006-03-15 11:31:56Z tcurdt $
29   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
30   */
31  public class LDC extends CPInstruction implements PushInstruction, ExceptionThrower,
32          TypedInstruction {
33  
34      /***
35       * Empty constructor needed for the Class.newInstance() statement in
36       * Instruction.readInstruction(). Not to be used otherwise.
37       */
38      LDC() {
39      }
40  
41  
42      public LDC(int index) {
43          super(org.apache.bcel.Constants.LDC_W, index);
44          setSize();
45      }
46  
47  
48      // Adjust to proper size
49      protected final void setSize() {
50          if (index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte?
51              opcode = org.apache.bcel.Constants.LDC;
52              length = 2;
53          } else {
54              opcode = org.apache.bcel.Constants.LDC_W;
55              length = 3;
56          }
57      }
58  
59  
60      /***
61       * Dump instruction as byte code to stream out.
62       * @param out Output stream
63       */
64      public void dump( DataOutputStream out ) throws IOException {
65          out.writeByte(opcode);
66          if (length == 2) {
67              out.writeByte(index);
68          } else {
69              out.writeShort(index);
70          }
71      }
72  
73  
74      /***
75       * Set the index to constant pool and adjust size.
76       */
77      public final void setIndex( int index ) {
78          super.setIndex(index);
79          setSize();
80      }
81  
82  
83      /***
84       * Read needed data (e.g. index) from file.
85       */
86      protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
87          length = 2;
88          index = bytes.readUnsignedByte();
89      }
90  
91  
92      public Object getValue( ConstantPoolGen cpg ) {
93          org.apache.bcel.classfile.Constant c = cpg.getConstantPool().getConstant(index);
94          switch (c.getTag()) {
95              case org.apache.bcel.Constants.CONSTANT_String:
96                  int i = ((org.apache.bcel.classfile.ConstantString) c).getStringIndex();
97                  c = cpg.getConstantPool().getConstant(i);
98                  return ((org.apache.bcel.classfile.ConstantUtf8) c).getBytes();
99              case org.apache.bcel.Constants.CONSTANT_Float:
100                 return new Float(((org.apache.bcel.classfile.ConstantFloat) c).getBytes());
101             case org.apache.bcel.Constants.CONSTANT_Integer:
102                 return new Integer(((org.apache.bcel.classfile.ConstantInteger) c).getBytes());
103             case org.apache.bcel.Constants.CONSTANT_Class:
104                 return c;
105             default: // Never reached
106                 throw new RuntimeException("Unknown or invalid constant type at " + index);
107         }
108     }
109 
110 
111     public Type getType( ConstantPoolGen cpg ) {
112         switch (cpg.getConstantPool().getConstant(index).getTag()) {
113             case org.apache.bcel.Constants.CONSTANT_String:
114                 return Type.STRING;
115             case org.apache.bcel.Constants.CONSTANT_Float:
116                 return Type.FLOAT;
117             case org.apache.bcel.Constants.CONSTANT_Integer:
118                 return Type.INT;
119             case org.apache.bcel.Constants.CONSTANT_Class:
120                 return Type.CLASS;
121             default: // Never reached
122                 throw new RuntimeException("Unknown or invalid constant type at " + index);
123         }
124     }
125 
126 
127     public Class[] getExceptions() {
128         return org.apache.bcel.ExceptionConstants.EXCS_STRING_RESOLUTION;
129     }
130 
131 
132     /***
133      * Call corresponding visitor method(s). The order is:
134      * Call visitor methods of implemented interfaces first, then
135      * call methods according to the class hierarchy in descending order,
136      * i.e., the most specific visitXXX() call comes last.
137      *
138      * @param v Visitor object
139      */
140     public void accept( Visitor v ) {
141         v.visitStackProducer(this);
142         v.visitPushInstruction(this);
143         v.visitExceptionThrower(this);
144         v.visitTypedInstruction(this);
145         v.visitCPInstruction(this);
146         v.visitLDC(this);
147     }
148 }