src/share/classes/com/sun/tools/classfile/ConstantPool.java

Tue, 20 Jan 2009 18:23:13 -0800

author
jjg
date
Tue, 20 Jan 2009 18:23:13 -0800
changeset 198
b4b1f7732289
parent 54
eaf608c64fec
child 229
03bcd66bd8e7
permissions
-rw-r--r--

6795903: fix latent build warnings in langtools repository
Reviewed-by: darcy

     1 /*
     2  * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.classfile;
    28 import java.io.IOException;
    30 /**
    31  * See JVMS3, section 4.5.
    32  *
    33  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
    34  *  you write code that depends on this, you do so at your own risk.
    35  *  This code and its internal interfaces are subject to change or
    36  *  deletion without notice.</b>
    37  */
    38 public class ConstantPool {
    40     public class InvalidIndex extends ConstantPoolException {
    41         private static final long serialVersionUID = -4350294289300939730L;
    42         InvalidIndex(int index) {
    43             super(index);
    44         }
    46         @Override
    47         public String getMessage() {
    48             // i18n
    49             return "invalid index #" + index;
    50         }
    51     }
    53     public class UnexpectedEntry extends ConstantPoolException {
    54         private static final long serialVersionUID = 6986335935377933211L;
    55         UnexpectedEntry(int index, int expected_tag, int found_tag) {
    56             super(index);
    57             this.expected_tag = expected_tag;
    58             this.found_tag = found_tag;
    59         }
    61         @Override
    62         public String getMessage() {
    63             // i18n?
    64             return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
    65         }
    67         public final int expected_tag;
    68         public final int found_tag;
    69     }
    71     public class InvalidEntry extends ConstantPoolException {
    72         private static final long serialVersionUID = 1000087545585204447L;
    73         InvalidEntry(int index, int tag) {
    74             super(index);
    75             this.tag = tag;
    76         }
    78         @Override
    79         public String getMessage() {
    80             // i18n?
    81             return "unexpected tag at #" + index + ": " + tag;
    82         }
    84         public final int tag;
    85     }
    87     public class EntryNotFound extends ConstantPoolException {
    88         private static final long serialVersionUID = 2885537606468581850L;
    89         EntryNotFound(Object value) {
    90             super(-1);
    91             this.value = value;
    92         }
    94         @Override
    95         public String getMessage() {
    96             // i18n?
    97             return "value not found: " + value;
    98         }
   100         public final Object value;
   101     }
   103     public static final int CONSTANT_Utf8 = 1;
   104     public static final int CONSTANT_Integer = 3;
   105     public static final int CONSTANT_Float = 4;
   106     public static final int CONSTANT_Long = 5;
   107     public static final int CONSTANT_Double = 6;
   108     public static final int CONSTANT_Class = 7;
   109     public static final int CONSTANT_String = 8;
   110     public static final int CONSTANT_Fieldref = 9;
   111     public static final int CONSTANT_Methodref = 10;
   112     public static final int CONSTANT_InterfaceMethodref = 11;
   113     public static final int CONSTANT_NameAndType = 12;
   115     ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
   116         int count = cr.readUnsignedShort();
   117         pool = new CPInfo[count];
   118         for (int i = 1; i < count; i++) {
   119             int tag = cr.readUnsignedByte();
   120             switch (tag) {
   121             case CONSTANT_Class:
   122                 pool[i] = new CONSTANT_Class_info(this, cr);
   123                 break;
   125             case CONSTANT_Double:
   126                 pool[i] = new CONSTANT_Double_info(cr);
   127                 i++;
   128                 break;
   130             case CONSTANT_Fieldref:
   131                 pool[i] = new CONSTANT_Fieldref_info(this, cr);
   132                 break;
   134             case CONSTANT_Float:
   135                 pool[i] = new CONSTANT_Float_info(cr);
   136                 break;
   138             case CONSTANT_Integer:
   139                 pool[i] = new CONSTANT_Integer_info(cr);
   140                 break;
   142             case CONSTANT_InterfaceMethodref:
   143                 pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
   144                 break;
   146             case CONSTANT_Long:
   147                 pool[i] = new CONSTANT_Long_info(cr);
   148                 i++;
   149                 break;
   151             case CONSTANT_Methodref:
   152                 pool[i] = new CONSTANT_Methodref_info(this, cr);
   153                 break;
   155             case CONSTANT_NameAndType:
   156                 pool[i] = new CONSTANT_NameAndType_info(this, cr);
   157                 break;
   159             case CONSTANT_String:
   160                 pool[i] = new CONSTANT_String_info(this, cr);
   161                 break;
   163             case CONSTANT_Utf8:
   164                 pool[i] = new CONSTANT_Utf8_info(cr);
   165                 break;
   167             default:
   168                 throw new InvalidEntry(i, tag);
   169             }
   170         }
   171     }
   173     public ConstantPool(CPInfo[] pool) {
   174         this.pool = pool;
   175     }
   177     public int size() {
   178         return pool.length;
   179     }
   181     public CPInfo get(int index) throws InvalidIndex {
   182         if (index <= 0 || index >= pool.length)
   183             throw new InvalidIndex(index);
   184         CPInfo info = pool[index];
   185         if (info == null) {
   186             // this occurs for indices referencing the "second half" of an
   187             // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
   188             throw new InvalidIndex(index);
   189         }
   190         return pool[index];
   191     }
   193     private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
   194         CPInfo info = get(index);
   195         if (info.getTag() != expected_type)
   196             throw new UnexpectedEntry(index, expected_type, info.getTag());
   197         return info;
   198     }
   200     public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
   201         return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
   202     }
   204     public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
   205         return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
   206     }
   208     public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
   209         return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
   210     }
   212     public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
   213         return getUTF8Info(index).value;
   214     }
   216     public int getUTF8Index(String value) throws EntryNotFound {
   217         for (int i = 1; i < pool.length; i++) {
   218             CPInfo info = pool[i];
   219             if (info instanceof CONSTANT_Utf8_info &&
   220                     ((CONSTANT_Utf8_info) info).value.equals(value))
   221                 return i;
   222         }
   223         throw new EntryNotFound(value);
   224     }
   226     private CPInfo[] pool;
   228     public interface Visitor<R,P> {
   229         R visitClass(CONSTANT_Class_info info, P p);
   230         R visitDouble(CONSTANT_Double_info info, P p);
   231         R visitFieldref(CONSTANT_Fieldref_info info, P p);
   232         R visitFloat(CONSTANT_Float_info info, P p);
   233         R visitInteger(CONSTANT_Integer_info info, P p);
   234         R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
   235         R visitLong(CONSTANT_Long_info info, P p);
   236         R visitNameAndType(CONSTANT_NameAndType_info info, P p);
   237         R visitMethodref(CONSTANT_Methodref_info info, P p);
   238         R visitString(CONSTANT_String_info info, P p);
   239         R visitUtf8(CONSTANT_Utf8_info info, P p);
   240     }
   242     public static abstract class CPInfo {
   243         CPInfo() {
   244             this.cp = null;
   245         }
   247         CPInfo(ConstantPool cp) {
   248             this.cp = cp;
   249         }
   251         public abstract int getTag();
   253         public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
   255         protected final ConstantPool cp;
   256     }
   258     public static abstract class CPRefInfo extends CPInfo {
   259         protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
   260             super(cp);
   261             this.tag = tag;
   262             class_index = cr.readUnsignedShort();
   263             name_and_type_index = cr.readUnsignedShort();
   264         }
   266         protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
   267             super(cp);
   268             this.tag = tag;
   269             this.class_index = class_index;
   270             this.name_and_type_index = name_and_type_index;
   271         }
   273         public int getTag() {
   274             return tag;
   275         }
   277         public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
   278             return cp.getClassInfo(class_index);
   279         }
   281         public String getClassName() throws ConstantPoolException {
   282             return cp.getClassInfo(class_index).getName();
   283         }
   285         public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
   286             return cp.getNameAndTypeInfo(name_and_type_index);
   287         }
   289         public final int tag;
   290         public final int class_index;
   291         public final int name_and_type_index;
   292     }
   294     public static class CONSTANT_Class_info extends CPInfo {
   295         CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
   296             super(cp);
   297             name_index = cr.readUnsignedShort();
   298         }
   300         public CONSTANT_Class_info(ConstantPool cp, int name_index) {
   301             super(cp);
   302             this.name_index = name_index;
   303         }
   305         public int getTag() {
   306             return CONSTANT_Class;
   307         }
   309         public String getName() throws ConstantPoolException {
   310             return cp.getUTF8Value(name_index);
   311         }
   313         @Override
   314         public String toString() {
   315             return "CONSTANT_Class_info[name_index: " + name_index + "]";
   316         }
   318         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   319             return visitor.visitClass(this, data);
   320         }
   322         public final int name_index;
   323     }
   325     public static class CONSTANT_Double_info extends CPInfo {
   326         CONSTANT_Double_info(ClassReader cr) throws IOException {
   327             value = cr.readDouble();
   328         }
   330         public CONSTANT_Double_info(double value) {
   331             this.value = value;
   332         }
   334         public int getTag() {
   335             return CONSTANT_Double;
   336         }
   338         @Override
   339         public String toString() {
   340             return "CONSTANT_Double_info[value: " + value + "]";
   341         }
   343         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   344             return visitor.visitDouble(this, data);
   345         }
   347         public final double value;
   348     }
   350     public static class CONSTANT_Fieldref_info extends CPRefInfo {
   351         CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
   352             super(cp, cr, CONSTANT_Fieldref);
   353         }
   355         public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
   356             super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
   357         }
   359         @Override
   360         public String toString() {
   361             return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
   362         }
   364         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   365             return visitor.visitFieldref(this, data);
   366         }
   367     }
   369     public static class CONSTANT_Float_info extends CPInfo {
   370         CONSTANT_Float_info(ClassReader cr) throws IOException {
   371             value = cr.readFloat();
   372         }
   374         public CONSTANT_Float_info(float value) {
   375             this.value = value;
   376         }
   378         public int getTag() {
   379             return CONSTANT_Float;
   380         }
   382         @Override
   383         public String toString() {
   384             return "CONSTANT_Float_info[value: " + value + "]";
   385         }
   387         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   388             return visitor.visitFloat(this, data);
   389         }
   391         public final float value;
   392     }
   394     public static class CONSTANT_Integer_info extends CPInfo {
   395         CONSTANT_Integer_info(ClassReader cr) throws IOException {
   396             value = cr.readInt();
   397         }
   399         public CONSTANT_Integer_info(int value) {
   400             this.value = value;
   401         }
   403         public int getTag() {
   404             return CONSTANT_Integer;
   405         }
   407         @Override
   408         public String toString() {
   409             return "CONSTANT_Integer_info[value: " + value + "]";
   410         }
   412         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   413             return visitor.visitInteger(this, data);
   414         }
   416         public final int value;
   417     }
   419     public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
   420         CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
   421             super(cp, cr, CONSTANT_InterfaceMethodref);
   422         }
   424         public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
   425             super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
   426         }
   428         @Override
   429         public String toString() {
   430             return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
   431         }
   433         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   434             return visitor.visitInterfaceMethodref(this, data);
   435         }
   436     }
   438     public static class CONSTANT_Long_info extends CPInfo {
   439         CONSTANT_Long_info(ClassReader cr) throws IOException {
   440             value = cr.readLong();
   441         }
   443         public CONSTANT_Long_info(long value) {
   444             this.value = value;
   445         }
   447         public int getTag() {
   448             return CONSTANT_Long;
   449         }
   451         @Override
   452         public String toString() {
   453             return "CONSTANT_Long_info[value: " + value + "]";
   454         }
   456         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   457             return visitor.visitLong(this, data);
   458         }
   460         public final long value;
   461     }
   463     public static class CONSTANT_Methodref_info extends CPRefInfo {
   464         CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
   465             super(cp, cr, CONSTANT_Methodref);
   466         }
   468         public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
   469             super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
   470         }
   472         @Override
   473         public String toString() {
   474             return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
   475         }
   477         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   478             return visitor.visitMethodref(this, data);
   479         }
   480     }
   482     public static class CONSTANT_NameAndType_info extends CPInfo {
   483         CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
   484             super(cp);
   485             name_index = cr.readUnsignedShort();
   486             type_index = cr.readUnsignedShort();
   487         }
   489         public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
   490             super(cp);
   491             this.name_index = name_index;
   492             this.type_index = type_index;
   493         }
   495         public int getTag() {
   496             return CONSTANT_NameAndType;
   497         }
   499         public String getName() throws ConstantPoolException {
   500             return cp.getUTF8Value(name_index);
   501         }
   503         public String getType() throws ConstantPoolException {
   504             return cp.getUTF8Value(type_index);
   505         }
   507         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   508             return visitor.visitNameAndType(this, data);
   509         }
   511         public final int name_index;
   512         public final int type_index;
   513     }
   515     public static class CONSTANT_String_info extends CPInfo {
   516         CONSTANT_String_info(ConstantPool cp, ClassReader cr) throws IOException {
   517             super(cp);
   518             string_index = cr.readUnsignedShort();
   519         }
   521         public CONSTANT_String_info(ConstantPool cp, int string_index) {
   522             super(cp);
   523             this.string_index = string_index;
   524         }
   526         public int getTag() {
   527             return CONSTANT_String;
   528         }
   530         public String getString() throws ConstantPoolException {
   531             return cp.getUTF8Value(string_index);
   532         }
   534         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   535             return visitor.visitString(this, data);
   536         }
   538         public final int string_index;
   539     }
   541     public static class CONSTANT_Utf8_info extends CPInfo {
   542         CONSTANT_Utf8_info(ClassReader cr) throws IOException {
   543             value = cr.readUTF();
   544         }
   546         public CONSTANT_Utf8_info(String value) {
   547             this.value = value;
   548         }
   550         public int getTag() {
   551             return CONSTANT_Utf8;
   552         }
   554         @Override
   555         public String toString() {
   556             return "CONSTANT_Utf8_info[value: " + value + "]";
   557         }
   559         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   560             return visitor.visitUtf8(this, data);
   561         }
   563         public final String value;
   564     }
   567 }

mercurial