mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
Initial load
This commit is contained in:
parent
686d76f772
commit
f57b87e8f6
2973 changed files with 295817 additions and 0 deletions
663
langtools/src/share/classes/sun/tools/javap/ClassData.java
Normal file
663
langtools/src/share/classes/sun/tools/javap/ClassData.java
Normal file
|
@ -0,0 +1,663 @@
|
|||
/*
|
||||
* Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
|
||||
package sun.tools.javap;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Central data repository of the Java Disassembler.
|
||||
* Stores all the information in java class file.
|
||||
*
|
||||
* @author Sucheta Dambalkar (Adopted code from jdis)
|
||||
*/
|
||||
public class ClassData implements RuntimeConstants {
|
||||
|
||||
private int magic;
|
||||
private int minor_version;
|
||||
private int major_version;
|
||||
private int cpool_count;
|
||||
private Object cpool[];
|
||||
private int access;
|
||||
private int this_class = 0;;
|
||||
private int super_class;
|
||||
private int interfaces_count;
|
||||
private int[] interfaces = new int[0];;
|
||||
private int fields_count;
|
||||
private FieldData[] fields;
|
||||
private int methods_count;
|
||||
private MethodData[] methods;
|
||||
private InnerClassData[] innerClasses;
|
||||
private int attributes_count;
|
||||
private AttrData[] attrs;
|
||||
private String classname;
|
||||
private String superclassname;
|
||||
private int source_cpx=0;
|
||||
private byte tags[];
|
||||
private Hashtable indexHashAscii = new Hashtable();
|
||||
private String pkgPrefix="";
|
||||
private int pkgPrefixLen=0;
|
||||
|
||||
/**
|
||||
* Read classfile to disassemble.
|
||||
*/
|
||||
public ClassData(InputStream infile){
|
||||
try{
|
||||
this.read(new DataInputStream(infile));
|
||||
}catch (FileNotFoundException ee) {
|
||||
error("cant read file");
|
||||
}catch (Error ee) {
|
||||
ee.printStackTrace();
|
||||
error("fatal error");
|
||||
} catch (Exception ee) {
|
||||
ee.printStackTrace();
|
||||
error("fatal exception");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and stores class file information.
|
||||
*/
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
// Read the header
|
||||
magic = in.readInt();
|
||||
if (magic != JAVA_MAGIC) {
|
||||
throw new ClassFormatError("wrong magic: " +
|
||||
toHex(magic) + ", expected " +
|
||||
toHex(JAVA_MAGIC));
|
||||
}
|
||||
minor_version = in.readShort();
|
||||
major_version = in.readShort();
|
||||
if (major_version != JAVA_VERSION) {
|
||||
}
|
||||
|
||||
// Read the constant pool
|
||||
readCP(in);
|
||||
access = in.readUnsignedShort();
|
||||
this_class = in.readUnsignedShort();
|
||||
super_class = in.readUnsignedShort();
|
||||
|
||||
//Read interfaces.
|
||||
interfaces_count = in.readUnsignedShort();
|
||||
if(interfaces_count > 0){
|
||||
interfaces = new int[interfaces_count];
|
||||
}
|
||||
for (int i = 0; i < interfaces_count; i++) {
|
||||
interfaces[i]=in.readShort();
|
||||
}
|
||||
|
||||
// Read the fields
|
||||
readFields(in);
|
||||
|
||||
// Read the methods
|
||||
readMethods(in);
|
||||
|
||||
// Read the attributes
|
||||
attributes_count = in.readUnsignedShort();
|
||||
attrs=new AttrData[attributes_count];
|
||||
for (int k = 0; k < attributes_count; k++) {
|
||||
int name_cpx=in.readUnsignedShort();
|
||||
if (getTag(name_cpx)==CONSTANT_UTF8
|
||||
&& getString(name_cpx).equals("SourceFile")
|
||||
){ if (in.readInt()!=2)
|
||||
throw new ClassFormatError("invalid attr length");
|
||||
source_cpx=in.readUnsignedShort();
|
||||
AttrData attr=new AttrData(this);
|
||||
attr.read(name_cpx);
|
||||
attrs[k]=attr;
|
||||
|
||||
} else if (getTag(name_cpx)==CONSTANT_UTF8
|
||||
&& getString(name_cpx).equals("InnerClasses")
|
||||
){ int length=in.readInt();
|
||||
int num=in.readUnsignedShort();
|
||||
if (2+num*8 != length)
|
||||
throw new ClassFormatError("invalid attr length");
|
||||
innerClasses=new InnerClassData[num];
|
||||
for (int j = 0; j < num; j++) {
|
||||
InnerClassData innerClass=new InnerClassData(this);
|
||||
innerClass.read(in);
|
||||
innerClasses[j]=innerClass;
|
||||
}
|
||||
AttrData attr=new AttrData(this);
|
||||
attr.read(name_cpx);
|
||||
attrs[k]=attr;
|
||||
} else {
|
||||
AttrData attr=new AttrData(this);
|
||||
attr.read(name_cpx, in);
|
||||
attrs[k]=attr;
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
} // end ClassData.read()
|
||||
|
||||
/**
|
||||
* Reads and stores constant pool info.
|
||||
*/
|
||||
void readCP(DataInputStream in) throws IOException {
|
||||
cpool_count = in.readUnsignedShort();
|
||||
tags = new byte[cpool_count];
|
||||
cpool = new Object[cpool_count];
|
||||
for (int i = 1; i < cpool_count; i++) {
|
||||
byte tag = in.readByte();
|
||||
|
||||
switch(tags[i] = tag) {
|
||||
case CONSTANT_UTF8:
|
||||
String str=in.readUTF();
|
||||
indexHashAscii.put(cpool[i] = str, new Integer(i));
|
||||
break;
|
||||
case CONSTANT_INTEGER:
|
||||
cpool[i] = new Integer(in.readInt());
|
||||
break;
|
||||
case CONSTANT_FLOAT:
|
||||
cpool[i] = new Float(in.readFloat());
|
||||
break;
|
||||
case CONSTANT_LONG:
|
||||
cpool[i++] = new Long(in.readLong());
|
||||
break;
|
||||
case CONSTANT_DOUBLE:
|
||||
cpool[i++] = new Double(in.readDouble());
|
||||
break;
|
||||
case CONSTANT_CLASS:
|
||||
case CONSTANT_STRING:
|
||||
cpool[i] = new CPX(in.readUnsignedShort());
|
||||
break;
|
||||
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
case CONSTANT_NAMEANDTYPE:
|
||||
cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
throw new ClassFormatError("invalid constant type: " + (int)tags[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and strores field info.
|
||||
*/
|
||||
protected void readFields(DataInputStream in) throws IOException {
|
||||
int fields_count = in.readUnsignedShort();
|
||||
fields=new FieldData[fields_count];
|
||||
for (int k = 0; k < fields_count; k++) {
|
||||
FieldData field=new FieldData(this);
|
||||
field.read(in);
|
||||
fields[k]=field;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and strores Method info.
|
||||
*/
|
||||
protected void readMethods(DataInputStream in) throws IOException {
|
||||
int methods_count = in.readUnsignedShort();
|
||||
methods=new MethodData[methods_count];
|
||||
for (int k = 0; k < methods_count ; k++) {
|
||||
MethodData method=new MethodData(this);
|
||||
method.read(in);
|
||||
methods[k]=method;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get a string
|
||||
*/
|
||||
public String getString(int n) {
|
||||
return (n == 0) ? null : (String)cpool[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* get the type of constant given an index
|
||||
*/
|
||||
public byte getTag(int n) {
|
||||
try{
|
||||
return tags[n];
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return (byte)100;
|
||||
}
|
||||
}
|
||||
|
||||
static final String hexString="0123456789ABCDEF";
|
||||
|
||||
public static char hexTable[]=hexString.toCharArray();
|
||||
|
||||
static String toHex(long val, int width) {
|
||||
StringBuffer s = new StringBuffer();
|
||||
for (int i=width-1; i>=0; i--)
|
||||
s.append(hexTable[((int)(val>>(4*i)))&0xF]);
|
||||
return "0x"+s.toString();
|
||||
}
|
||||
|
||||
static String toHex(long val) {
|
||||
int width;
|
||||
for (width=16; width>0; width--) {
|
||||
if ((val>>(width-1)*4)!=0) break;
|
||||
}
|
||||
return toHex(val, width);
|
||||
}
|
||||
|
||||
static String toHex(int val) {
|
||||
int width;
|
||||
for (width=8; width>0; width--) {
|
||||
if ((val>>(width-1)*4)!=0) break;
|
||||
}
|
||||
return toHex(val, width);
|
||||
}
|
||||
|
||||
public void error(String msg) {
|
||||
System.err.println("ERROR:" +msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this class.
|
||||
*/
|
||||
public String getClassName() {
|
||||
String res=null;
|
||||
if (this_class==0) {
|
||||
return res;
|
||||
}
|
||||
int tcpx;
|
||||
try {
|
||||
if (tags[this_class]!=CONSTANT_CLASS) {
|
||||
return res; //"<CP["+cpx+"] is not a Class> ";
|
||||
}
|
||||
tcpx=((CPX)cpool[this_class]).cpx;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "#"+cpx+"// invalid constant pool index";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
|
||||
try {
|
||||
return (String)(cpool[tcpx]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool index";
|
||||
} catch (ClassCastException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool reference";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of class at perticular index.
|
||||
*/
|
||||
public String getClassName(int cpx) {
|
||||
String res="#"+cpx;
|
||||
if (cpx==0) {
|
||||
return res;
|
||||
}
|
||||
int scpx;
|
||||
try {
|
||||
if (tags[cpx]!=CONSTANT_CLASS) {
|
||||
return res; //"<CP["+cpx+"] is not a Class> ";
|
||||
}
|
||||
scpx=((CPX)cpool[cpx]).cpx;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "#"+cpx+"// invalid constant pool index";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
res="#"+scpx;
|
||||
try {
|
||||
return (String)(cpool[scpx]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool index";
|
||||
} catch (ClassCastException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool reference";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if it is a class
|
||||
*/
|
||||
public boolean isClass() {
|
||||
if((access & ACC_INTERFACE) == 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if it is a interface.
|
||||
*/
|
||||
public boolean isInterface(){
|
||||
if((access & ACC_INTERFACE) != 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this member is public, false otherwise.
|
||||
*/
|
||||
public boolean isPublic(){
|
||||
return (access & ACC_PUBLIC) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the access of this class or interface.
|
||||
*/
|
||||
public String[] getAccess(){
|
||||
Vector v = new Vector();
|
||||
if ((access & ACC_PUBLIC) !=0) v.addElement("public");
|
||||
if ((access & ACC_FINAL) !=0) v.addElement("final");
|
||||
if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
|
||||
String[] accflags = new String[v.size()];
|
||||
v.copyInto(accflags);
|
||||
return accflags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of innerclasses.
|
||||
*/
|
||||
public InnerClassData[] getInnerClasses(){
|
||||
return innerClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of attributes.
|
||||
*/
|
||||
public AttrData[] getAttributes(){
|
||||
return attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if superbit is set.
|
||||
*/
|
||||
public boolean isSuperSet(){
|
||||
if ((access & ACC_SUPER) !=0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns super class name.
|
||||
*/
|
||||
public String getSuperClassName(){
|
||||
String res=null;
|
||||
if (super_class==0) {
|
||||
return res;
|
||||
}
|
||||
int scpx;
|
||||
try {
|
||||
if (tags[super_class]!=CONSTANT_CLASS) {
|
||||
return res; //"<CP["+cpx+"] is not a Class> ";
|
||||
}
|
||||
scpx=((CPX)cpool[super_class]).cpx;
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "#"+cpx+"// invalid constant pool index";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
|
||||
try {
|
||||
return (String)(cpool[scpx]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool index";
|
||||
} catch (ClassCastException e) {
|
||||
return res; // "class #"+scpx+"// invalid constant pool reference";
|
||||
} catch (Throwable e) {
|
||||
return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of super interfaces.
|
||||
*/
|
||||
public String[] getSuperInterfaces(){
|
||||
String interfacenames[] = new String[interfaces.length];
|
||||
int interfacecpx = -1;
|
||||
for(int i = 0; i < interfaces.length; i++){
|
||||
interfacecpx=((CPX)cpool[interfaces[i]]).cpx;
|
||||
interfacenames[i] = (String)(cpool[interfacecpx]);
|
||||
}
|
||||
return interfacenames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string at prticular constant pool index.
|
||||
*/
|
||||
public String getStringValue(int cpoolx) {
|
||||
try {
|
||||
return ((String)cpool[cpoolx]);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return "//invalid constant pool index:"+cpoolx;
|
||||
} catch (ClassCastException e) {
|
||||
return "//invalid constant pool ref:"+cpoolx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of field info.
|
||||
*/
|
||||
public FieldData[] getFields(){
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of method info.
|
||||
*/
|
||||
public MethodData[] getMethods(){
|
||||
return methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns constant pool entry at that index.
|
||||
*/
|
||||
public CPX2 getCpoolEntry(int cpx){
|
||||
return ((CPX2)(cpool[cpx]));
|
||||
}
|
||||
|
||||
public Object getCpoolEntryobj(int cpx){
|
||||
return (cpool[cpx]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index of this class.
|
||||
*/
|
||||
public int getthis_cpx(){
|
||||
return this_class;
|
||||
}
|
||||
|
||||
public String TagString (int tag) {
|
||||
String res=Tables.tagName(tag);
|
||||
if (res==null) return "BOGUS_TAG:"+tag;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns string at that index.
|
||||
*/
|
||||
public String StringValue(int cpx) {
|
||||
if (cpx==0) return "#0";
|
||||
int tag;
|
||||
Object x;
|
||||
String suffix="";
|
||||
try {
|
||||
tag=tags[cpx];
|
||||
x=cpool[cpx];
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
return "<Incorrect CP index:"+cpx+">";
|
||||
}
|
||||
|
||||
if (x==null) return "<NULL>";
|
||||
switch (tag) {
|
||||
case CONSTANT_UTF8: {
|
||||
StringBuffer sb=new StringBuffer();
|
||||
String s=(String)x;
|
||||
for (int k=0; k<s.length(); k++) {
|
||||
char c=s.charAt(k);
|
||||
switch (c) {
|
||||
case '\t': sb.append('\\').append('t'); break;
|
||||
case '\n': sb.append('\\').append('n'); break;
|
||||
case '\r': sb.append('\\').append('r'); break;
|
||||
case '\"': sb.append('\\').append('\"'); break;
|
||||
default: sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
case CONSTANT_DOUBLE: {
|
||||
Double d=(Double)x;
|
||||
String sd=d.toString();
|
||||
return sd+"d";
|
||||
}
|
||||
case CONSTANT_FLOAT: {
|
||||
Float f=(Float)x;
|
||||
String sf=(f).toString();
|
||||
return sf+"f";
|
||||
}
|
||||
case CONSTANT_LONG: {
|
||||
Long ln = (Long)x;
|
||||
return ln.toString()+'l';
|
||||
}
|
||||
case CONSTANT_INTEGER: {
|
||||
Integer in = (Integer)x;
|
||||
return in.toString();
|
||||
}
|
||||
case CONSTANT_CLASS:
|
||||
return javaName(getClassName(cpx));
|
||||
case CONSTANT_STRING:
|
||||
return StringValue(((CPX)x).cpx);
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
//return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
|
||||
return javaName(getClassName(((CPX2)x).cpx1))+"."+StringValue(((CPX2)x).cpx2);
|
||||
|
||||
case CONSTANT_NAMEANDTYPE:
|
||||
return getName(((CPX2)x).cpx1)+":"+StringValue(((CPX2)x).cpx2);
|
||||
default:
|
||||
return "UnknownTag"; //TBD
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns resolved java type name.
|
||||
*/
|
||||
public String javaName(String name) {
|
||||
if( name==null) return "null";
|
||||
int len=name.length();
|
||||
if (len==0) return "\"\"";
|
||||
int cc='/';
|
||||
fullname: { // xxx/yyy/zzz
|
||||
int cp;
|
||||
for (int k=0; k<len; k += Character.charCount(cp)) {
|
||||
cp=name.codePointAt(k);
|
||||
if (cc=='/') {
|
||||
if (!Character.isJavaIdentifierStart(cp)) break fullname;
|
||||
} else if (cp!='/') {
|
||||
if (!Character.isJavaIdentifierPart(cp)) break fullname;
|
||||
}
|
||||
cc=cp;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
return "\""+name+"\"";
|
||||
}
|
||||
|
||||
public String getName(int cpx) {
|
||||
String res;
|
||||
try {
|
||||
return javaName((String)cpool[cpx]); //.replace('/','.');
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
return "<invalid constant pool index:"+cpx+">";
|
||||
} catch (ClassCastException e) {
|
||||
return "<invalid constant pool ref:"+cpx+">";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unqualified class name.
|
||||
*/
|
||||
public String getShortClassName(int cpx) {
|
||||
String classname=javaName(getClassName(cpx));
|
||||
pkgPrefixLen=classname.lastIndexOf("/")+1;
|
||||
if (pkgPrefixLen!=0) {
|
||||
pkgPrefix=classname.substring(0,pkgPrefixLen);
|
||||
if (classname.startsWith(pkgPrefix)) {
|
||||
return classname.substring(pkgPrefixLen);
|
||||
}
|
||||
}
|
||||
return classname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns source file name.
|
||||
*/
|
||||
public String getSourceName(){
|
||||
return getName(source_cpx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns package name.
|
||||
*/
|
||||
public String getPkgName(){
|
||||
String classname=getClassName(this_class);
|
||||
pkgPrefixLen=classname.lastIndexOf("/")+1;
|
||||
if (pkgPrefixLen!=0) {
|
||||
pkgPrefix=classname.substring(0,pkgPrefixLen);
|
||||
return("package "+pkgPrefix.substring(0,pkgPrefixLen-1)+";\n");
|
||||
}else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns total constant pool entry count.
|
||||
*/
|
||||
public int getCpoolCount(){
|
||||
return cpool_count;
|
||||
}
|
||||
|
||||
public String StringTag(int cpx) {
|
||||
byte tag=0;
|
||||
String str=null;
|
||||
try {
|
||||
if (cpx==0) throw new IndexOutOfBoundsException();
|
||||
tag=tags[cpx];
|
||||
return TagString(tag);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
str="Incorrect CP index:"+cpx;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns minor version of class file.
|
||||
*/
|
||||
public int getMinor_version(){
|
||||
return minor_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns major version of class file.
|
||||
*/
|
||||
public int getMajor_version(){
|
||||
return major_version;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue