Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java
38899 views
/*1* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.classfile;2627import java.io.DataOutputStream;28import java.io.IOException;29import java.io.OutputStream;30import java.util.Iterator;3132/**33* See JVMS, section 4.5.34*35* <p><b>This is NOT part of any supported API.36* If you write code that depends on this, you do so at your own risk.37* This code and its internal interfaces are subject to change or38* deletion without notice.</b>39*/40public class ConstantPool {4142public static class InvalidIndex extends ConstantPoolException {43private static final long serialVersionUID = -4350294289300939730L;44InvalidIndex(int index) {45super(index);46}4748@Override49public String getMessage() {50// i18n51return "invalid index #" + index;52}53}5455public static class UnexpectedEntry extends ConstantPoolException {56private static final long serialVersionUID = 6986335935377933211L;57UnexpectedEntry(int index, int expected_tag, int found_tag) {58super(index);59this.expected_tag = expected_tag;60this.found_tag = found_tag;61}6263@Override64public String getMessage() {65// i18n?66return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;67}6869public final int expected_tag;70public final int found_tag;71}7273public static class InvalidEntry extends ConstantPoolException {74private static final long serialVersionUID = 1000087545585204447L;75InvalidEntry(int index, int tag) {76super(index);77this.tag = tag;78}7980@Override81public String getMessage() {82// i18n?83return "unexpected tag at #" + index + ": " + tag;84}8586public final int tag;87}8889public static class EntryNotFound extends ConstantPoolException {90private static final long serialVersionUID = 2885537606468581850L;91EntryNotFound(Object value) {92super(-1);93this.value = value;94}9596@Override97public String getMessage() {98// i18n?99return "value not found: " + value;100}101102public final Object value;103}104105public static final int CONSTANT_Utf8 = 1;106public static final int CONSTANT_Integer = 3;107public static final int CONSTANT_Float = 4;108public static final int CONSTANT_Long = 5;109public static final int CONSTANT_Double = 6;110public static final int CONSTANT_Class = 7;111public static final int CONSTANT_String = 8;112public static final int CONSTANT_Fieldref = 9;113public static final int CONSTANT_Methodref = 10;114public static final int CONSTANT_InterfaceMethodref = 11;115public static final int CONSTANT_NameAndType = 12;116public static final int CONSTANT_MethodHandle = 15;117public static final int CONSTANT_MethodType = 16;118public static final int CONSTANT_InvokeDynamic = 18;119120public static enum RefKind {121REF_getField(1, "getfield"),122REF_getStatic(2, "getstatic"),123REF_putField(3, "putfield"),124REF_putStatic(4, "putstatic"),125REF_invokeVirtual(5, "invokevirtual"),126REF_invokeStatic(6, "invokestatic"),127REF_invokeSpecial(7, "invokespecial"),128REF_newInvokeSpecial(8, "newinvokespecial"),129REF_invokeInterface(9, "invokeinterface");130131public final int tag;132public final String name;133134RefKind(int tag, String name) {135this.tag = tag;136this.name = name;137}138139static RefKind getRefkind(int tag) {140switch(tag) {141case 1:142return REF_getField;143case 2:144return REF_getStatic;145case 3:146return REF_putField;147case 4:148return REF_putStatic;149case 5:150return REF_invokeVirtual;151case 6:152return REF_invokeStatic;153case 7:154return REF_invokeSpecial;155case 8:156return REF_newInvokeSpecial;157case 9:158return REF_invokeInterface;159default:160return null;161}162}163}164165ConstantPool(ClassReader cr) throws IOException, InvalidEntry {166int count = cr.readUnsignedShort();167pool = new CPInfo[count];168for (int i = 1; i < count; i++) {169int tag = cr.readUnsignedByte();170switch (tag) {171case CONSTANT_Class:172pool[i] = new CONSTANT_Class_info(this, cr);173break;174175case CONSTANT_Double:176pool[i] = new CONSTANT_Double_info(cr);177i++;178break;179180case CONSTANT_Fieldref:181pool[i] = new CONSTANT_Fieldref_info(this, cr);182break;183184case CONSTANT_Float:185pool[i] = new CONSTANT_Float_info(cr);186break;187188case CONSTANT_Integer:189pool[i] = new CONSTANT_Integer_info(cr);190break;191192case CONSTANT_InterfaceMethodref:193pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);194break;195196case CONSTANT_InvokeDynamic:197pool[i] = new CONSTANT_InvokeDynamic_info(this, cr);198break;199200case CONSTANT_Long:201pool[i] = new CONSTANT_Long_info(cr);202i++;203break;204205case CONSTANT_MethodHandle:206pool[i] = new CONSTANT_MethodHandle_info(this, cr);207break;208209case CONSTANT_MethodType:210pool[i] = new CONSTANT_MethodType_info(this, cr);211break;212213case CONSTANT_Methodref:214pool[i] = new CONSTANT_Methodref_info(this, cr);215break;216217case CONSTANT_NameAndType:218pool[i] = new CONSTANT_NameAndType_info(this, cr);219break;220221case CONSTANT_String:222pool[i] = new CONSTANT_String_info(this, cr);223break;224225case CONSTANT_Utf8:226pool[i] = new CONSTANT_Utf8_info(cr);227break;228229default:230throw new InvalidEntry(i, tag);231}232}233}234235public ConstantPool(CPInfo[] pool) {236this.pool = pool;237}238239public int size() {240return pool.length;241}242243public int byteLength() {244int length = 2;245for (int i = 1; i < size(); ) {246CPInfo cpInfo = pool[i];247length += cpInfo.byteLength();248i += cpInfo.size();249}250return length;251}252253public CPInfo get(int index) throws InvalidIndex {254if (index <= 0 || index >= pool.length)255throw new InvalidIndex(index);256CPInfo info = pool[index];257if (info == null) {258// this occurs for indices referencing the "second half" of an259// 8 byte constant, such as CONSTANT_Double or CONSTANT_Long260throw new InvalidIndex(index);261}262return pool[index];263}264265private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {266CPInfo info = get(index);267if (info.getTag() != expected_type)268throw new UnexpectedEntry(index, expected_type, info.getTag());269return info;270}271272public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {273return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));274}275276public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {277return ((CONSTANT_Class_info) get(index, CONSTANT_Class));278}279280public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {281return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));282}283284public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {285return getUTF8Info(index).value;286}287288public int getUTF8Index(String value) throws EntryNotFound {289for (int i = 1; i < pool.length; i++) {290CPInfo info = pool[i];291if (info instanceof CONSTANT_Utf8_info &&292((CONSTANT_Utf8_info) info).value.equals(value))293return i;294}295throw new EntryNotFound(value);296}297298public Iterable<CPInfo> entries() {299return new Iterable<CPInfo>() {300public Iterator<CPInfo> iterator() {301return new Iterator<CPInfo>() {302303public boolean hasNext() {304return next < pool.length;305}306307public CPInfo next() {308current = pool[next];309switch (current.getTag()) {310case CONSTANT_Double:311case CONSTANT_Long:312next += 2;313break;314default:315next += 1;316}317return current;318}319320public void remove() {321throw new UnsupportedOperationException();322}323324private CPInfo current;325private int next = 1;326327};328}329};330}331332private CPInfo[] pool;333334public interface Visitor<R,P> {335R visitClass(CONSTANT_Class_info info, P p);336R visitDouble(CONSTANT_Double_info info, P p);337R visitFieldref(CONSTANT_Fieldref_info info, P p);338R visitFloat(CONSTANT_Float_info info, P p);339R visitInteger(CONSTANT_Integer_info info, P p);340R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);341R visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, P p);342R visitLong(CONSTANT_Long_info info, P p);343R visitNameAndType(CONSTANT_NameAndType_info info, P p);344R visitMethodref(CONSTANT_Methodref_info info, P p);345R visitMethodHandle(CONSTANT_MethodHandle_info info, P p);346R visitMethodType(CONSTANT_MethodType_info info, P p);347R visitString(CONSTANT_String_info info, P p);348R visitUtf8(CONSTANT_Utf8_info info, P p);349}350351public static abstract class CPInfo {352CPInfo() {353this.cp = null;354}355356CPInfo(ConstantPool cp) {357this.cp = cp;358}359360public abstract int getTag();361362/** The number of slots in the constant pool used by this entry.363* 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. */364public int size() {365return 1;366}367368public abstract int byteLength();369370public abstract <R,D> R accept(Visitor<R,D> visitor, D data);371372protected final ConstantPool cp;373}374375public static abstract class CPRefInfo extends CPInfo {376protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {377super(cp);378this.tag = tag;379class_index = cr.readUnsignedShort();380name_and_type_index = cr.readUnsignedShort();381}382383protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {384super(cp);385this.tag = tag;386this.class_index = class_index;387this.name_and_type_index = name_and_type_index;388}389390public int getTag() {391return tag;392}393394public int byteLength() {395return 5;396}397398public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {399return cp.getClassInfo(class_index);400}401402public String getClassName() throws ConstantPoolException {403return cp.getClassInfo(class_index).getName();404}405406public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {407return cp.getNameAndTypeInfo(name_and_type_index);408}409410public final int tag;411public final int class_index;412public final int name_and_type_index;413}414415public static class CONSTANT_Class_info extends CPInfo {416CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {417super(cp);418name_index = cr.readUnsignedShort();419}420421public CONSTANT_Class_info(ConstantPool cp, int name_index) {422super(cp);423this.name_index = name_index;424}425426public int getTag() {427return CONSTANT_Class;428}429430public int byteLength() {431return 3;432}433434/**435* Get the raw value of the class referenced by this constant pool entry.436* This will either be the name of the class, in internal form, or a437* descriptor for an array class.438* @return the raw value of the class439*/440public String getName() throws ConstantPoolException {441return cp.getUTF8Value(name_index);442}443444/**445* If this constant pool entry identifies either a class or interface type,446* or a possibly multi-dimensional array of a class of interface type,447* return the name of the class or interface in internal form. Otherwise,448* (i.e. if this is a possibly multi-dimensional array of a primitive type),449* return null.450* @return the base class or interface name451*/452public String getBaseName() throws ConstantPoolException {453String name = getName();454if (name.startsWith("[")) {455int index = name.indexOf("[L");456if (index == -1)457return null;458return name.substring(index + 2, name.length() - 1);459} else460return name;461}462463public int getDimensionCount() throws ConstantPoolException {464String name = getName();465int count = 0;466while (name.charAt(count) == '[')467count++;468return count;469}470471@Override472public String toString() {473return "CONSTANT_Class_info[name_index: " + name_index + "]";474}475476public <R, D> R accept(Visitor<R, D> visitor, D data) {477return visitor.visitClass(this, data);478}479480public final int name_index;481}482483public static class CONSTANT_Double_info extends CPInfo {484CONSTANT_Double_info(ClassReader cr) throws IOException {485value = cr.readDouble();486}487488public CONSTANT_Double_info(double value) {489this.value = value;490}491492public int getTag() {493return CONSTANT_Double;494}495496public int byteLength() {497return 9;498}499500@Override501public int size() {502return 2;503}504505@Override506public String toString() {507return "CONSTANT_Double_info[value: " + value + "]";508}509510public <R, D> R accept(Visitor<R, D> visitor, D data) {511return visitor.visitDouble(this, data);512}513514public final double value;515}516517public static class CONSTANT_Fieldref_info extends CPRefInfo {518CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {519super(cp, cr, CONSTANT_Fieldref);520}521522public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {523super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);524}525526@Override527public String toString() {528return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";529}530531public <R, D> R accept(Visitor<R, D> visitor, D data) {532return visitor.visitFieldref(this, data);533}534}535536public static class CONSTANT_Float_info extends CPInfo {537CONSTANT_Float_info(ClassReader cr) throws IOException {538value = cr.readFloat();539}540541public CONSTANT_Float_info(float value) {542this.value = value;543}544545public int getTag() {546return CONSTANT_Float;547}548549public int byteLength() {550return 5;551}552553@Override554public String toString() {555return "CONSTANT_Float_info[value: " + value + "]";556}557558public <R, D> R accept(Visitor<R, D> visitor, D data) {559return visitor.visitFloat(this, data);560}561562public final float value;563}564565public static class CONSTANT_Integer_info extends CPInfo {566CONSTANT_Integer_info(ClassReader cr) throws IOException {567value = cr.readInt();568}569570public CONSTANT_Integer_info(int value) {571this.value = value;572}573574public int getTag() {575return CONSTANT_Integer;576}577578public int byteLength() {579return 5;580}581582@Override583public String toString() {584return "CONSTANT_Integer_info[value: " + value + "]";585}586587public <R, D> R accept(Visitor<R, D> visitor, D data) {588return visitor.visitInteger(this, data);589}590591public final int value;592}593594public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {595CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {596super(cp, cr, CONSTANT_InterfaceMethodref);597}598599public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {600super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);601}602603@Override604public String toString() {605return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";606}607608public <R, D> R accept(Visitor<R, D> visitor, D data) {609return visitor.visitInterfaceMethodref(this, data);610}611}612613public static class CONSTANT_InvokeDynamic_info extends CPInfo {614CONSTANT_InvokeDynamic_info(ConstantPool cp, ClassReader cr) throws IOException {615super(cp);616bootstrap_method_attr_index = cr.readUnsignedShort();617name_and_type_index = cr.readUnsignedShort();618}619620public CONSTANT_InvokeDynamic_info(ConstantPool cp, int bootstrap_method_index, int name_and_type_index) {621super(cp);622this.bootstrap_method_attr_index = bootstrap_method_index;623this.name_and_type_index = name_and_type_index;624}625626public int getTag() {627return CONSTANT_InvokeDynamic;628}629630public int byteLength() {631return 5;632}633634@Override635public String toString() {636return "CONSTANT_InvokeDynamic_info[bootstrap_method_index: " + bootstrap_method_attr_index + ", name_and_type_index: " + name_and_type_index + "]";637}638639public <R, D> R accept(Visitor<R, D> visitor, D data) {640return visitor.visitInvokeDynamic(this, data);641}642643public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {644return cp.getNameAndTypeInfo(name_and_type_index);645}646647public final int bootstrap_method_attr_index;648public final int name_and_type_index;649}650651public static class CONSTANT_Long_info extends CPInfo {652CONSTANT_Long_info(ClassReader cr) throws IOException {653value = cr.readLong();654}655656public CONSTANT_Long_info(long value) {657this.value = value;658}659660public int getTag() {661return CONSTANT_Long;662}663664@Override665public int size() {666return 2;667}668669public int byteLength() {670return 9;671}672673@Override674public String toString() {675return "CONSTANT_Long_info[value: " + value + "]";676}677678public <R, D> R accept(Visitor<R, D> visitor, D data) {679return visitor.visitLong(this, data);680}681682public final long value;683}684685public static class CONSTANT_MethodHandle_info extends CPInfo {686CONSTANT_MethodHandle_info(ConstantPool cp, ClassReader cr) throws IOException {687super(cp);688reference_kind = RefKind.getRefkind(cr.readUnsignedByte());689reference_index = cr.readUnsignedShort();690}691692public CONSTANT_MethodHandle_info(ConstantPool cp, RefKind ref_kind, int member_index) {693super(cp);694this.reference_kind = ref_kind;695this.reference_index = member_index;696}697698public int getTag() {699return CONSTANT_MethodHandle;700}701702public int byteLength() {703return 4;704}705706@Override707public String toString() {708return "CONSTANT_MethodHandle_info[ref_kind: " + reference_kind + ", member_index: " + reference_index + "]";709}710711public <R, D> R accept(Visitor<R, D> visitor, D data) {712return visitor.visitMethodHandle(this, data);713}714715public CPRefInfo getCPRefInfo() throws ConstantPoolException {716int expected = CONSTANT_Methodref;717int actual = cp.get(reference_index).getTag();718// allow these tag types also:719switch (actual) {720case CONSTANT_Fieldref:721case CONSTANT_InterfaceMethodref:722expected = actual;723}724return (CPRefInfo) cp.get(reference_index, expected);725}726727public final RefKind reference_kind;728public final int reference_index;729}730731public static class CONSTANT_MethodType_info extends CPInfo {732CONSTANT_MethodType_info(ConstantPool cp, ClassReader cr) throws IOException {733super(cp);734descriptor_index = cr.readUnsignedShort();735}736737public CONSTANT_MethodType_info(ConstantPool cp, int signature_index) {738super(cp);739this.descriptor_index = signature_index;740}741742public int getTag() {743return CONSTANT_MethodType;744}745746public int byteLength() {747return 3;748}749750@Override751public String toString() {752return "CONSTANT_MethodType_info[signature_index: " + descriptor_index + "]";753}754755public <R, D> R accept(Visitor<R, D> visitor, D data) {756return visitor.visitMethodType(this, data);757}758759public String getType() throws ConstantPoolException {760return cp.getUTF8Value(descriptor_index);761}762763public final int descriptor_index;764}765766public static class CONSTANT_Methodref_info extends CPRefInfo {767CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {768super(cp, cr, CONSTANT_Methodref);769}770771public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {772super(cp, CONSTANT_Methodref, class_index, name_and_type_index);773}774775@Override776public String toString() {777return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";778}779780public <R, D> R accept(Visitor<R, D> visitor, D data) {781return visitor.visitMethodref(this, data);782}783}784785public static class CONSTANT_NameAndType_info extends CPInfo {786CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {787super(cp);788name_index = cr.readUnsignedShort();789type_index = cr.readUnsignedShort();790}791792public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {793super(cp);794this.name_index = name_index;795this.type_index = type_index;796}797798public int getTag() {799return CONSTANT_NameAndType;800}801802public int byteLength() {803return 5;804}805806public String getName() throws ConstantPoolException {807return cp.getUTF8Value(name_index);808}809810public String getType() throws ConstantPoolException {811return cp.getUTF8Value(type_index);812}813814public <R, D> R accept(Visitor<R, D> visitor, D data) {815return visitor.visitNameAndType(this, data);816}817818@Override819public String toString() {820return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";821}822823public final int name_index;824public final int type_index;825}826827public static class CONSTANT_String_info extends CPInfo {828CONSTANT_String_info(ConstantPool cp, ClassReader cr) throws IOException {829super(cp);830string_index = cr.readUnsignedShort();831}832833public CONSTANT_String_info(ConstantPool cp, int string_index) {834super(cp);835this.string_index = string_index;836}837838public int getTag() {839return CONSTANT_String;840}841842public int byteLength() {843return 3;844}845846public String getString() throws ConstantPoolException {847return cp.getUTF8Value(string_index);848}849850public <R, D> R accept(Visitor<R, D> visitor, D data) {851return visitor.visitString(this, data);852}853854@Override855public String toString() {856return "CONSTANT_String_info[class_index: " + string_index + "]";857}858859public final int string_index;860}861862public static class CONSTANT_Utf8_info extends CPInfo {863CONSTANT_Utf8_info(ClassReader cr) throws IOException {864value = cr.readUTF();865}866867public CONSTANT_Utf8_info(String value) {868this.value = value;869}870871public int getTag() {872return CONSTANT_Utf8;873}874875public int byteLength() {876class SizeOutputStream extends OutputStream {877@Override878public void write(int b) {879size++;880}881int size;882}883SizeOutputStream sizeOut = new SizeOutputStream();884DataOutputStream out = new DataOutputStream(sizeOut);885try { out.writeUTF(value); } catch (IOException ignore) { }886return 1 + sizeOut.size;887}888889@Override890public String toString() {891if (value.length() < 32 && isPrintableAscii(value))892return "CONSTANT_Utf8_info[value: \"" + value + "\"]";893else894return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]";895}896897static boolean isPrintableAscii(String s) {898for (int i = 0; i < s.length(); i++) {899char c = s.charAt(i);900if (c < 32 || c >= 127)901return false;902}903return true;904}905906public <R, D> R accept(Visitor<R, D> visitor, D data) {907return visitor.visitUtf8(this, data);908}909910public final String value;911}912913}914915916