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

Tue, 03 Jun 2008 13:26:47 -0700

author
jjg
date
Tue, 03 Jun 2008 13:26:47 -0700
changeset 46
7708bd6d800d
child 52
3cb4fb6e0720
permissions
-rw-r--r--

4075303: Use javap to enquire aboput a specific inner class
4348375: Javap is not internationalized
4459541: "javap -l" shows line numbers as signed short; they should be unsigned
4501660: change diagnostic of -help as 'print this help message and exit'
4776241: unused source file in javap...
4870651: javap should recognize generics, varargs, enum
4876942: javap invoked without args does not print help screen
4880663: javap could output whitespace between class name and opening brace
4975569: javap doesn't print new flag bits
6271787: javap dumps LocalVariableTypeTable attribute in hex, needs to print a table
6305779: javap: support annotations
6439940: Clean up javap implementation
6469569: wrong check of searchpath in JavapEnvironment
6474890: javap does not open .zip files in -classpath
6587786: Javap throws error : "ERROR:Could not find <classname>" for JRE classes
6622215: javap ignores certain relevant access flags
6622216: javap names some attributes incorrectly
6622232: javap gets whitespace confused
6622260: javap prints negative bytes incorrectly in hex
Reviewed-by: ksrini

     1 /*
     2  * Copyright 2007 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         InvalidIndex(int index) {
    42             super(index);
    43         }
    45         @Override
    46         public String getMessage() {
    47             // i18n
    48             return "invalid index #" + index;
    49         }
    50     }
    52     public class UnexpectedEntry extends ConstantPoolException {
    53         UnexpectedEntry(int index, int expected_tag, int found_tag) {
    54             super(index);
    55             this.expected_tag = expected_tag;
    56             this.found_tag = found_tag;
    57         }
    59         @Override
    60         public String getMessage() {
    61             // i18n?
    62             return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
    63         }
    65         public final int expected_tag;
    66         public final int found_tag;
    67     }
    69     public class InvalidEntry extends ConstantPoolException {
    70         InvalidEntry(int index, int tag) {
    71             super(index);
    72             this.tag = tag;
    73         }
    75         @Override
    76         public String getMessage() {
    77             // i18n?
    78             return "unexpected tag at #" + index + ": " + tag;
    79         }
    81         public final int tag;
    82     }
    84     public class EntryNotFound extends ConstantPoolException {
    85         EntryNotFound(Object value) {
    86             super(-1);
    87             this.value = value;
    88         }
    90         @Override
    91         public String getMessage() {
    92             // i18n?
    93             return "value not found: " + value;
    94         }
    96         public final Object value;
    97     }
    99     public static final int CONSTANT_Utf8 = 1;
   100     public static final int CONSTANT_Integer = 3;
   101     public static final int CONSTANT_Float = 4;
   102     public static final int CONSTANT_Long = 5;
   103     public static final int CONSTANT_Double = 6;
   104     public static final int CONSTANT_Class = 7;
   105     public static final int CONSTANT_String = 8;
   106     public static final int CONSTANT_Fieldref = 9;
   107     public static final int CONSTANT_Methodref = 10;
   108     public static final int CONSTANT_InterfaceMethodref = 11;
   109     public static final int CONSTANT_NameAndType = 12;
   111     ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
   112         int count = cr.readUnsignedShort();
   113         pool = new CPInfo[count];
   114         for (int i = 1; i < count; i++) {
   115             int tag = cr.readUnsignedByte();
   116             switch (tag) {
   117             case CONSTANT_Class:
   118                 pool[i] = new CONSTANT_Class_info(this, cr);
   119                 break;
   121             case CONSTANT_Double:
   122                 pool[i] = new CONSTANT_Double_info(cr);
   123                 i++;
   124                 break;
   126             case CONSTANT_Fieldref:
   127                 pool[i] = new CONSTANT_Fieldref_info(this, cr);
   128                 break;
   130             case CONSTANT_Float:
   131                 pool[i] = new CONSTANT_Float_info(cr);
   132                 break;
   134             case CONSTANT_Integer:
   135                 pool[i] = new CONSTANT_Integer_info(cr);
   136                 break;
   138             case CONSTANT_InterfaceMethodref:
   139                 pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
   140                 break;
   142             case CONSTANT_Long:
   143                 pool[i] = new CONSTANT_Long_info(cr);
   144                 i++;
   145                 break;
   147             case CONSTANT_Methodref:
   148                 pool[i] = new CONSTANT_Methodref_info(this, cr);
   149                 break;
   151             case CONSTANT_NameAndType:
   152                 pool[i] = new CONSTANT_NameAndType_info(this, cr);
   153                 break;
   155             case CONSTANT_String:
   156                 pool[i] = new CONSTANT_String_info(cr);
   157                 break;
   159             case CONSTANT_Utf8:
   160                 pool[i] = new CONSTANT_Utf8_info(cr);
   161                 break;
   163             default:
   164                 throw new InvalidEntry(i, tag);
   165             }
   166         }
   167     }
   169     public ConstantPool(CPInfo[] pool) {
   170         this.pool = pool;
   171     }
   173     public int size() {
   174         return pool.length;
   175     }
   177     public CPInfo get(int index) throws InvalidIndex {
   178         if (index <= 0 || index >= pool.length)
   179             throw new InvalidIndex(index);
   180         CPInfo info = pool[index];
   181         if (info == null) {
   182             // this occurs for indices referencing the "second half" of an
   183             // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
   184             throw new InvalidIndex(index);
   185         }
   186         return pool[index];
   187     }
   189     private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
   190         CPInfo info = get(index);
   191         if (info.getTag() != expected_type)
   192             throw new UnexpectedEntry(index, expected_type, info.getTag());
   193         return info;
   194     }
   196     public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
   197         return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
   198     }
   200     public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
   201         return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
   202     }
   204     public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
   205         return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
   206     }
   208     public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
   209         return getUTF8Info(index).value;
   210     }
   212     public int getUTF8Index(String value) throws EntryNotFound {
   213         for (int i = 1; i < pool.length; i++) {
   214             CPInfo info = pool[i];
   215             if (info instanceof CONSTANT_Utf8_info &&
   216                     ((CONSTANT_Utf8_info) info).value.equals(value))
   217                 return i;
   218         }
   219         throw new EntryNotFound(value);
   220     }
   222     private CPInfo[] pool;
   224     public interface Visitor<R,P> {
   225         R visitClass(CONSTANT_Class_info info, P p);
   226         R visitDouble(CONSTANT_Double_info info, P p);
   227         R visitFieldref(CONSTANT_Fieldref_info info, P p);
   228         R visitFloat(CONSTANT_Float_info info, P p);
   229         R visitInteger(CONSTANT_Integer_info info, P p);
   230         R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
   231         R visitLong(CONSTANT_Long_info info, P p);
   232         R visitNameAndType(CONSTANT_NameAndType_info info, P p);
   233         R visitMethodref(CONSTANT_Methodref_info info, P p);
   234         R visitString(CONSTANT_String_info info, P p);
   235         R visitUtf8(CONSTANT_Utf8_info info, P p);
   236     }
   238     public static abstract class CPInfo {
   239         CPInfo() {
   240             this.cp = null;
   241         }
   243         CPInfo(ConstantPool cp) {
   244             this.cp = cp;
   245         }
   247         public abstract int getTag();
   249         public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
   251         protected final ConstantPool cp;
   252     }
   254     public static abstract class CPRefInfo extends CPInfo {
   255         protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
   256             super(cp);
   257             this.tag = tag;
   258             class_index = cr.readUnsignedShort();
   259             name_and_type_index = cr.readUnsignedShort();
   260         }
   262         protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
   263             super(cp);
   264             this.tag = tag;
   265             this.class_index = class_index;
   266             this.name_and_type_index = name_and_type_index;
   267         }
   269         public int getTag() {
   270             return tag;
   271         }
   273         public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
   274             return cp.getClassInfo(class_index);
   275         }
   277         public String getClassName() throws ConstantPoolException {
   278             return cp.getClassInfo(class_index).getName();
   279         }
   281         public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
   282             return cp.getNameAndTypeInfo(name_and_type_index);
   283         }
   285         public final int tag;
   286         public final int class_index;
   287         public final int name_and_type_index;
   288     }
   290     public static class CONSTANT_Class_info extends CPInfo {
   291         CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
   292             super(cp);
   293             name_index = cr.readUnsignedShort();
   294         }
   296         public CONSTANT_Class_info(ConstantPool cp, int name_index) {
   297             super(cp);
   298             this.name_index = name_index;
   299         }
   301         public int getTag() {
   302             return CONSTANT_Class;
   303         }
   305         public String getName() throws ConstantPoolException {
   306             return cp.getUTF8Value(name_index);
   307         }
   309         @Override
   310         public String toString() {
   311             return "CONSTANT_Class_info[name_index: " + name_index + "]";
   312         }
   314         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   315             return visitor.visitClass(this, data);
   316         }
   318         public final int name_index;
   319     }
   321     public static class CONSTANT_Double_info extends CPInfo {
   322         CONSTANT_Double_info(ClassReader cr) throws IOException {
   323             value = cr.readDouble();
   324         }
   326         public CONSTANT_Double_info(double value) {
   327             this.value = value;
   328         }
   330         public int getTag() {
   331             return CONSTANT_Double;
   332         }
   334         @Override
   335         public String toString() {
   336             return "CONSTANT_Double_info[value: " + value + "]";
   337         }
   339         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   340             return visitor.visitDouble(this, data);
   341         }
   343         public final double value;
   344     }
   346     public static class CONSTANT_Fieldref_info extends CPRefInfo {
   347         CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
   348             super(cp, cr, CONSTANT_Fieldref);
   349         }
   351         public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
   352             super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
   353         }
   355         @Override
   356         public String toString() {
   357             return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
   358         }
   360         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   361             return visitor.visitFieldref(this, data);
   362         }
   363     }
   365     public static class CONSTANT_Float_info extends CPInfo {
   366         CONSTANT_Float_info(ClassReader cr) throws IOException {
   367             value = cr.readFloat();
   368         }
   370         public CONSTANT_Float_info(float value) {
   371             this.value = value;
   372         }
   374         public int getTag() {
   375             return CONSTANT_Float;
   376         }
   378         @Override
   379         public String toString() {
   380             return "CONSTANT_Float_info[value: " + value + "]";
   381         }
   383         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   384             return visitor.visitFloat(this, data);
   385         }
   387         public final float value;
   388     }
   390     public static class CONSTANT_Integer_info extends CPInfo {
   391         CONSTANT_Integer_info(ClassReader cr) throws IOException {
   392             value = cr.readInt();
   393         }
   395         public CONSTANT_Integer_info(int value) {
   396             this.value = value;
   397         }
   399         public int getTag() {
   400             return CONSTANT_Integer;
   401         }
   403         @Override
   404         public String toString() {
   405             return "CONSTANT_Integer_info[value: " + value + "]";
   406         }
   408         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   409             return visitor.visitInteger(this, data);
   410         }
   412         public final int value;
   413     }
   415     public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
   416         CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
   417             super(cp, cr, CONSTANT_InterfaceMethodref);
   418         }
   420         public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
   421             super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
   422         }
   424         @Override
   425         public String toString() {
   426             return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
   427         }
   429         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   430             return visitor.visitInterfaceMethodref(this, data);
   431         }
   432     }
   434     public static class CONSTANT_Long_info extends CPInfo {
   435         CONSTANT_Long_info(ClassReader cr) throws IOException {
   436             value = cr.readLong();
   437         }
   439         public CONSTANT_Long_info(long value) {
   440             this.value = value;
   441         }
   443         public int getTag() {
   444             return CONSTANT_Long;
   445         }
   447         @Override
   448         public String toString() {
   449             return "CONSTANT_Long_info[value: " + value + "]";
   450         }
   452         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   453             return visitor.visitLong(this, data);
   454         }
   456         public final long value;
   457     }
   459     public static class CONSTANT_Methodref_info extends CPRefInfo {
   460         CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
   461             super(cp, cr, CONSTANT_Methodref);
   462         }
   464         public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
   465             super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
   466         }
   468         @Override
   469         public String toString() {
   470             return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
   471         }
   473         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   474             return visitor.visitMethodref(this, data);
   475         }
   476     }
   478     public static class CONSTANT_NameAndType_info extends CPInfo {
   479         CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
   480             super(cp);
   481             name_index = cr.readUnsignedShort();
   482             type_index = cr.readUnsignedShort();
   483         }
   485         public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
   486             super(cp);
   487             this.name_index = name_index;
   488             this.type_index = type_index;
   489         }
   491         public int getTag() {
   492             return CONSTANT_NameAndType;
   493         }
   495         public String getName() throws ConstantPoolException {
   496             return cp.getUTF8Value(name_index);
   497         }
   499         public String getType() throws ConstantPoolException {
   500             return cp.getUTF8Value(type_index);
   501         }
   503         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   504             return visitor.visitNameAndType(this, data);
   505         }
   507         public final int name_index;
   508         public final int type_index;
   509     }
   511     public static class CONSTANT_String_info extends CPInfo {
   512         CONSTANT_String_info(ClassReader cr) throws IOException {
   513             string_index = cr.readUnsignedShort();
   514         }
   516         public CONSTANT_String_info(ConstantPool cp, int string_index) {
   517             super(cp);
   518             this.string_index = string_index;
   519         }
   521         public int getTag() {
   522             return CONSTANT_String;
   523         }
   525         public String getString() throws ConstantPoolException {
   526             return cp.getUTF8Value(string_index);
   527         }
   529         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   530             return visitor.visitString(this, data);
   531         }
   533         public final int string_index;
   534     }
   536     public static class CONSTANT_Utf8_info extends CPInfo {
   537         CONSTANT_Utf8_info(ClassReader cr) throws IOException {
   538             value = cr.readUTF();
   539         }
   541         public CONSTANT_Utf8_info(String value) {
   542             this.value = value;
   543         }
   545         public int getTag() {
   546             return CONSTANT_Utf8;
   547         }
   549         @Override
   550         public String toString() {
   551             return "CONSTANT_Utf8_info[value: " + value + "]";
   552         }
   554         public <R, D> R accept(Visitor<R, D> visitor, D data) {
   555             return visitor.visitUtf8(this, data);
   556         }
   558         public final String value;
   559     }
   562 }

mercurial