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