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 import java.io.*; 25 import com.sun.org.apache.bcel.internal.util.ByteSequence; 26 27 /** 28 * LDC - Push item from constant pool. 29 * 30 * <PRE>Stack: ... -> ..., item</PRE> 31 * 32 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> 33 */ 34 public class LDC extends CPInstruction 35 implements PushInstruction, ExceptionThrower, TypedInstruction { 36 /** 37 * Empty constructor needed for the Class.newInstance() statement in 38 * Instruction.readInstruction(). Not to be used otherwise. 39 */ 40 LDC() {} 41 42 public LDC(int index) { 43 super(com.sun.org.apache.bcel.internal.Constants.LDC_W, index); 44 setSize(); 45 } 46 47 // Adjust to proper size 48 protected final void setSize() { 49 if(index <= com.sun.org.apache.bcel.internal.Constants.MAX_BYTE) { // Fits in one byte? 50 opcode = com.sun.org.apache.bcel.internal.Constants.LDC; 51 length = 2; 52 } else { 53 opcode = com.sun.org.apache.bcel.internal.Constants.LDC_W; 54 length = 3; 55 } 56 } 57 58 /** 59 * Dump instruction as byte code to stream out. 60 * @param out Output stream 61 */ 62 public void dump(DataOutputStream out) throws IOException { 63 out.writeByte(opcode); 64 65 if(length == 2) 66 out.writeByte(index); 67 else // Applies for LDC_W 68 out.writeShort(index); 69 } 70 71 /** 72 * Set the index to constant pool and adjust size. 73 */ 74 public final void setIndex(int index) { 75 super.setIndex(index); 76 setSize(); 77 } 78 79 /** 80 * Read needed data (e.g. index) from file. 81 */ 82 protected void initFromFile(ByteSequence bytes, boolean wide) 83 throws IOException 84 { 85 length = 2; 86 index = bytes.readUnsignedByte(); 87 } 88 89 public Object getValue(ConstantPoolGen cpg) { 90 com.sun.org.apache.bcel.internal.classfile.Constant c = cpg.getConstantPool().getConstant(index); 91 92 switch(c.getTag()) { 93 case com.sun.org.apache.bcel.internal.Constants.CONSTANT_String: 94 int i = ((com.sun.org.apache.bcel.internal.classfile.ConstantString)c).getStringIndex(); 95 c = cpg.getConstantPool().getConstant(i); 96 return ((com.sun.org.apache.bcel.internal.classfile.ConstantUtf8)c).getBytes(); 97 98 case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Float: 99 return new Float(((com.sun.org.apache.bcel.internal.classfile.ConstantFloat)c).getBytes()); 100 101 case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Integer: 102 return new Integer(((com.sun.org.apache.bcel.internal.classfile.ConstantInteger)c).getBytes()); 103 104 default: // Never reached 105 throw new RuntimeException("Unknown or invalid constant type at " + index); 106 } 107 } 108 109 public Type getType(ConstantPoolGen cpg) { 110 switch(cpg.getConstantPool().getConstant(index).getTag()) { 111 case com.sun.org.apache.bcel.internal.Constants.CONSTANT_String: return Type.STRING; 112 case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Float: return Type.FLOAT; 113 case com.sun.org.apache.bcel.internal.Constants.CONSTANT_Integer: return Type.INT; 114 default: // Never reached 115 throw new RuntimeException("Unknown or invalid constant type at " + index); 116 } 117 } 118 119 public Class[] getExceptions() { 120 return com.sun.org.apache.bcel.internal.ExceptionConstants.EXCS_STRING_RESOLUTION; 121 } 122 123 /** 124 * Call corresponding visitor method(s). The order is: 125 * Call visitor methods of implemented interfaces first, then 126 * call methods according to the class hierarchy in descending order, 127 * i.e., the most specific visitXXX() call comes last. 128 * 129 * @param v Visitor object 130 */ 131 public void accept(Visitor v) { 132 v.visitStackProducer(this); 133 v.visitPushInstruction(this); 134 v.visitExceptionThrower(this); 135 v.visitTypedInstruction(this); 136 v.visitCPInstruction(this); 137 v.visitLDC(this); 138 } 139 }