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
This commit is contained in:
parent
e3ba3ecd1d
commit
0a7516d744
@ -66,7 +66,7 @@ javac.no.jdk.warnings = -XDignore.symbol.file=true
|
||||
# set the following to -version to verify the versions of javac being used
|
||||
javac.version.opt =
|
||||
# in time, there should be no exceptions to -Xlint:all
|
||||
javac.lint.opts = -Xlint:all,-unchecked,-deprecation,-fallthrough,-cast,-serial -Werror
|
||||
javac.lint.opts = -Xlint:all,-deprecation,-fallthrough,-serial -Werror
|
||||
|
||||
# options for the <javadoc> task for javac
|
||||
javadoc.jls3.url=http://java.sun.com/docs/books/jls/
|
||||
@ -120,6 +120,8 @@ javah.tests = \
|
||||
tools/javah/
|
||||
|
||||
javap.includes = \
|
||||
com/sun/tools/classfile/ \
|
||||
com/sun/tools/javap/ \
|
||||
sun/tools/javap/
|
||||
|
||||
javap.tests = \
|
||||
|
@ -136,7 +136,7 @@
|
||||
<arg value="-html:${findbugs.home}/src/xsl/fancy.xsl"/>
|
||||
<arg value="${dist.findbugs.dir}/findbugs.xml"/>
|
||||
<redirector output="${dist.findbugs.dir}/findbugs.html"/>
|
||||
</exec>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="coverage" depends="-def-cobertura,build-all-classes,instrument-classes,jtreg,coverage-report"/>
|
||||
@ -301,14 +301,15 @@
|
||||
jarmainclass="sun.tools.javap.Main"/>
|
||||
</target>
|
||||
|
||||
<target name="build-classes-javap" depends="build-bootstrap-javac">
|
||||
<target name="build-classes-javap" depends="build-classes-javac">
|
||||
<build-classes name="javap" includes="${javap.includes}"/>
|
||||
</target>
|
||||
|
||||
<target name="build-javap" depends="build-bootstrap-javac">
|
||||
<target name="build-javap" depends="build-javac">
|
||||
<build-tool name="javap"
|
||||
includes="${javap.includes}"
|
||||
jarmainclass="sun.tools.javap.Main"/>
|
||||
jarmainclass="sun.tools.javap.Main"
|
||||
jarclasspath="javac.jar"/>
|
||||
</target>
|
||||
|
||||
<!-- (no javadoc for javap) -->
|
||||
@ -480,7 +481,7 @@
|
||||
destdir="@{gensrc.dir}"
|
||||
includes="@{includes}"/>
|
||||
<copy todir="@{gensrc.dir}">
|
||||
<fileset dir="${src.classes.dir}" includes="${javac.includes}"/>
|
||||
<fileset dir="${src.classes.dir}" includes="@{includes}"/>
|
||||
<globmapper from="*.properties-template" to="*.properties"/>
|
||||
<filterset begintoken="$(" endtoken=")">
|
||||
<filter token="JDK_VERSION" value="${jdk.version}"/>
|
||||
|
@ -157,5 +157,5 @@
|
||||
</action>
|
||||
|
||||
<action name="javadoc">
|
||||
<target>javadoc-nb</target>
|
||||
<target>-javadoc-nb</target>
|
||||
</action>
|
||||
|
@ -157,5 +157,5 @@
|
||||
</action>
|
||||
|
||||
<action name="javadoc">
|
||||
<target>javadoc-nb</target>
|
||||
<target>-javadoc-nb</target>
|
||||
</action>
|
||||
|
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* See JVMS3, sections 4.2, 4.6, 4.7.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class AccessFlags {
|
||||
public static final int ACC_PUBLIC = 0x0001; // class, inner, field, method
|
||||
public static final int ACC_PRIVATE = 0x0002; // inner, field, method
|
||||
public static final int ACC_PROTECTED = 0x0004; // inner, field, method
|
||||
public static final int ACC_STATIC = 0x0008; // inner, field, method
|
||||
public static final int ACC_FINAL = 0x0010; // class, inner, field, method
|
||||
public static final int ACC_SUPER = 0x0020; // class
|
||||
public static final int ACC_SYNCHRONIZED = 0x0020; // method
|
||||
public static final int ACC_VOLATILE = 0x0040; // field
|
||||
public static final int ACC_BRIDGE = 0x0040; // method
|
||||
public static final int ACC_TRANSIENT = 0x0080; // field
|
||||
public static final int ACC_VARARGS = 0x0080; // method
|
||||
public static final int ACC_NATIVE = 0x0100; // method
|
||||
public static final int ACC_INTERFACE = 0x0200; // class, inner
|
||||
public static final int ACC_ABSTRACT = 0x0400; // class, inner, method
|
||||
public static final int ACC_STRICT = 0x0800; // method
|
||||
public static final int ACC_SYNTHETIC = 0x1000; // class, inner, field, method
|
||||
public static final int ACC_ANNOTATION = 0x2000; // class, inner
|
||||
public static final int ACC_ENUM = 0x4000; // class, inner, field
|
||||
public static final int ACC_MODULE = 0x8000; // class, inner, field, method
|
||||
|
||||
private static enum Type { Class, InnerClass, Field, Method};
|
||||
|
||||
AccessFlags(ClassReader cr) throws IOException {
|
||||
this(cr.readUnsignedShort());
|
||||
}
|
||||
|
||||
public AccessFlags(int flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
public AccessFlags ignore(int mask) {
|
||||
return new AccessFlags(flags & ~mask);
|
||||
}
|
||||
|
||||
public boolean is(int mask) {
|
||||
return (flags & mask) != 0;
|
||||
}
|
||||
|
||||
private static final int[] classModifiers = {
|
||||
ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_MODULE
|
||||
};
|
||||
|
||||
private static final int[] classFlags = {
|
||||
ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT,
|
||||
ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
|
||||
};
|
||||
|
||||
public Set<String> getClassModifiers() {
|
||||
int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
|
||||
return getModifiers(f, classModifiers, Type.Class);
|
||||
}
|
||||
|
||||
public Set<String> getClassFlags() {
|
||||
return getFlags(classFlags, Type.Class);
|
||||
}
|
||||
|
||||
private static final int[] innerClassModifiers = {
|
||||
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
|
||||
ACC_ABSTRACT, ACC_MODULE
|
||||
};
|
||||
|
||||
private static final int[] innerClassFlags = {
|
||||
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER,
|
||||
ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
|
||||
};
|
||||
|
||||
public Set<String> getInnerClassModifiers() {
|
||||
int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags);
|
||||
return getModifiers(f, innerClassModifiers, Type.InnerClass);
|
||||
}
|
||||
|
||||
public Set<String> getInnerClassFlags() {
|
||||
return getFlags(innerClassFlags, Type.InnerClass);
|
||||
}
|
||||
|
||||
private static final int[] fieldModifiers = {
|
||||
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
|
||||
ACC_VOLATILE, ACC_TRANSIENT, ACC_MODULE
|
||||
};
|
||||
|
||||
private static final int[] fieldFlags = {
|
||||
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
|
||||
ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM, ACC_MODULE
|
||||
};
|
||||
|
||||
public Set<String> getFieldModifiers() {
|
||||
return getModifiers(fieldModifiers, Type.Field);
|
||||
}
|
||||
|
||||
public Set<String> getFieldFlags() {
|
||||
return getFlags(fieldFlags, Type.Field);
|
||||
}
|
||||
|
||||
private static final int[] methodModifiers = {
|
||||
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
|
||||
ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT, ACC_MODULE
|
||||
};
|
||||
|
||||
private static final int[] methodFlags = {
|
||||
ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
|
||||
ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT,
|
||||
ACC_STRICT, ACC_SYNTHETIC, ACC_MODULE
|
||||
};
|
||||
|
||||
public Set<String> getMethodModifiers() {
|
||||
return getModifiers(methodModifiers, Type.Method);
|
||||
}
|
||||
|
||||
public Set<String> getMethodFlags() {
|
||||
return getFlags(methodFlags, Type.Method);
|
||||
}
|
||||
|
||||
private Set<String> getModifiers(int[] modifierFlags, Type t) {
|
||||
return getModifiers(flags, modifierFlags, t);
|
||||
}
|
||||
|
||||
private static Set<String> getModifiers(int flags, int[] modifierFlags, Type t) {
|
||||
Set<String> s = new LinkedHashSet<String>();
|
||||
for (int m: modifierFlags) {
|
||||
if ((flags & m) != 0)
|
||||
s.add(flagToModifier(m, t));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private Set<String> getFlags(int[] expectedFlags, Type t) {
|
||||
Set<String> s = new LinkedHashSet<String>();
|
||||
int f = flags;
|
||||
for (int e: expectedFlags) {
|
||||
if ((f & e) != 0) {
|
||||
s.add(flagToName(e, t));
|
||||
f = f & ~e;
|
||||
}
|
||||
}
|
||||
while (f != 0) {
|
||||
int bit = Integer.highestOneBit(f);
|
||||
s.add("0x" + Integer.toHexString(bit));
|
||||
f = f & ~bit;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private static String flagToModifier(int flag, Type t) {
|
||||
switch (flag) {
|
||||
case ACC_PUBLIC:
|
||||
return "public";
|
||||
case ACC_PRIVATE:
|
||||
return "private";
|
||||
case ACC_PROTECTED:
|
||||
return "protected";
|
||||
case ACC_STATIC:
|
||||
return "static";
|
||||
case ACC_FINAL:
|
||||
return "final";
|
||||
case ACC_SYNCHRONIZED:
|
||||
return "synchronized";
|
||||
case 0x80:
|
||||
return (t == Type.Field ? "transient" : null);
|
||||
case ACC_VOLATILE:
|
||||
return "volatile";
|
||||
case ACC_NATIVE:
|
||||
return "native";
|
||||
case ACC_ABSTRACT:
|
||||
return "abstract";
|
||||
case ACC_STRICT:
|
||||
return "strictfp";
|
||||
case ACC_MODULE:
|
||||
return "module";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String flagToName(int flag, Type t) {
|
||||
switch (flag) {
|
||||
case ACC_PUBLIC:
|
||||
return "ACC_PUBLIC";
|
||||
case ACC_PRIVATE:
|
||||
return "ACC_PRIVATE";
|
||||
case ACC_PROTECTED:
|
||||
return "ACC_PROTECTED";
|
||||
case ACC_STATIC:
|
||||
return "ACC_STATIC";
|
||||
case ACC_FINAL:
|
||||
return "ACC_FINAL";
|
||||
case 0x20:
|
||||
return (t == Type.Class ? "ACC_SUPER" : "ACC_SYNCHRONIZED");
|
||||
case 0x40:
|
||||
return (t == Type.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
|
||||
case 0x80:
|
||||
return (t == Type.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
|
||||
case ACC_NATIVE:
|
||||
return "ACC_NATIVE";
|
||||
case ACC_INTERFACE:
|
||||
return "ACC_INTERFACE";
|
||||
case ACC_ABSTRACT:
|
||||
return "ACC_ABSTRACT";
|
||||
case ACC_STRICT:
|
||||
return "ACC_STRICT";
|
||||
case ACC_SYNTHETIC:
|
||||
return "ACC_SYNTHETIC";
|
||||
case ACC_ANNOTATION:
|
||||
return "ACC_ANNOTATION";
|
||||
case ACC_ENUM:
|
||||
return "ACC_ENUM";
|
||||
case ACC_MODULE:
|
||||
return "ACC_MODULE";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final int flags;
|
||||
}
|
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.16.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Annotation {
|
||||
static class InvalidAnnotation extends AttributeException {
|
||||
InvalidAnnotation(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
Annotation(ClassReader cr) throws IOException, InvalidAnnotation {
|
||||
type_index = cr.readUnsignedShort();
|
||||
num_element_value_pairs = cr.readUnsignedShort();
|
||||
element_value_pairs = new element_value_pair[num_element_value_pairs];
|
||||
for (int i = 0; i < element_value_pairs.length; i++)
|
||||
element_value_pairs[i] = new element_value_pair(cr);
|
||||
}
|
||||
|
||||
public Annotation(ConstantPool constant_pool,
|
||||
int type_index,
|
||||
element_value_pair[] element_value_pairs) {
|
||||
this.type_index = type_index;
|
||||
num_element_value_pairs = element_value_pairs.length;
|
||||
this.element_value_pairs = element_value_pairs;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
int n = 2 /*type_index*/ + 2 /*num_element_value_pairs*/;
|
||||
for (element_value_pair pair: element_value_pairs)
|
||||
n += pair.length();
|
||||
return n;
|
||||
}
|
||||
|
||||
public final int type_index;
|
||||
public final int num_element_value_pairs;
|
||||
public final element_value_pair element_value_pairs[];
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.16.1.
|
||||
*/
|
||||
public static abstract class element_value {
|
||||
public static element_value read(ClassReader cr)
|
||||
throws IOException, InvalidAnnotation {
|
||||
int tag = cr.readUnsignedByte();
|
||||
switch (tag) {
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'F':
|
||||
case 'I':
|
||||
case 'J':
|
||||
case 'S':
|
||||
case 'Z':
|
||||
case 's':
|
||||
return new Primitive_element_value(cr, tag);
|
||||
|
||||
case 'e':
|
||||
return new Enum_element_value(cr, tag);
|
||||
|
||||
case 'c':
|
||||
return new Class_element_value(cr, tag);
|
||||
|
||||
case '@':
|
||||
return new Annotation_element_value(cr, tag);
|
||||
|
||||
case '[':
|
||||
return new Array_element_value(cr, tag);
|
||||
|
||||
default:
|
||||
throw new InvalidAnnotation("unrecognized tag: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
protected element_value(int tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public abstract int length();
|
||||
|
||||
public abstract <R,P> R accept(Visitor<R,P> visitor, P p);
|
||||
|
||||
public interface Visitor<R,P> {
|
||||
R visitPrimitive(Primitive_element_value ev, P p);
|
||||
R visitEnum(Enum_element_value ev, P p);
|
||||
R visitClass(Class_element_value ev, P p);
|
||||
R visitAnnotation(Annotation_element_value ev, P p);
|
||||
R visitArray(Array_element_value ev, P p);
|
||||
}
|
||||
|
||||
public final int tag;
|
||||
}
|
||||
|
||||
public static class Primitive_element_value extends element_value {
|
||||
Primitive_element_value(ClassReader cr, int tag) throws IOException {
|
||||
super(tag);
|
||||
const_value_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public <R,P> R accept(Visitor<R,P> visitor, P p) {
|
||||
return visitor.visitPrimitive(this, p);
|
||||
}
|
||||
|
||||
public final int const_value_index;
|
||||
|
||||
}
|
||||
|
||||
public static class Enum_element_value extends element_value {
|
||||
Enum_element_value(ClassReader cr, int tag) throws IOException {
|
||||
super(tag);
|
||||
type_name_index = cr.readUnsignedShort();
|
||||
const_name_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public <R,P> R accept(Visitor<R,P> visitor, P p) {
|
||||
return visitor.visitEnum(this, p);
|
||||
}
|
||||
|
||||
public final int type_name_index;
|
||||
public final int const_name_index;
|
||||
}
|
||||
|
||||
public static class Class_element_value extends element_value {
|
||||
Class_element_value(ClassReader cr, int tag) throws IOException {
|
||||
super(tag);
|
||||
class_info_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public <R,P> R accept(Visitor<R,P> visitor, P p) {
|
||||
return visitor.visitClass(this, p);
|
||||
}
|
||||
|
||||
public final int class_info_index;
|
||||
}
|
||||
|
||||
public static class Annotation_element_value extends element_value {
|
||||
Annotation_element_value(ClassReader cr, int tag)
|
||||
throws IOException, InvalidAnnotation {
|
||||
super(tag);
|
||||
annotation_value = new Annotation(cr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return annotation_value.length();
|
||||
}
|
||||
|
||||
public <R,P> R accept(Visitor<R,P> visitor, P p) {
|
||||
return visitor.visitAnnotation(this, p);
|
||||
}
|
||||
|
||||
public final Annotation annotation_value;
|
||||
}
|
||||
|
||||
public static class Array_element_value extends element_value {
|
||||
Array_element_value(ClassReader cr, int tag)
|
||||
throws IOException, InvalidAnnotation {
|
||||
super(tag);
|
||||
num_values = cr.readUnsignedShort();
|
||||
values = new element_value[num_values];
|
||||
for (int i = 0; i < values.length; i++)
|
||||
values[i] = element_value.read(cr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
int n = 2;
|
||||
for (int i = 0; i < values.length; i++)
|
||||
n += values[i].length();
|
||||
return n;
|
||||
}
|
||||
|
||||
public <R,P> R accept(Visitor<R,P> visitor, P p) {
|
||||
return visitor.visitArray(this, p);
|
||||
}
|
||||
|
||||
public final int num_values;
|
||||
public final element_value[] values;
|
||||
}
|
||||
|
||||
public static class element_value_pair {
|
||||
element_value_pair(ClassReader cr)
|
||||
throws IOException, InvalidAnnotation {
|
||||
element_name_index = cr.readUnsignedShort();
|
||||
value = element_value.read(cr);
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 2 + value.length();
|
||||
}
|
||||
|
||||
public final int element_name_index;
|
||||
public final element_value value;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.15.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class AnnotationDefault_attribute extends Attribute {
|
||||
AnnotationDefault_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(name_index, length);
|
||||
default_value = Annotation.element_value.read(cr);
|
||||
}
|
||||
|
||||
public AnnotationDefault_attribute(ConstantPool constant_pool, Annotation.element_value default_value)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.AnnotationDefault), default_value);
|
||||
}
|
||||
|
||||
public AnnotationDefault_attribute(int name_index, Annotation.element_value default_value) {
|
||||
super(name_index, default_value.length());
|
||||
this.default_value = default_value;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitAnnotationDefault(this, data);
|
||||
}
|
||||
|
||||
public final Annotation.element_value default_value;
|
||||
}
|
||||
|
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
|
||||
public abstract class Attribute {
|
||||
public static final String AnnotationDefault = "AnnotationDefault";
|
||||
public static final String CharacterRangeTable = "CharacterRangeTable";
|
||||
public static final String Code = "Code";
|
||||
public static final String ConstantValue = "ConstantValue";
|
||||
public static final String CompilationID = "CompilationID";
|
||||
public static final String Deprecated = "Deprecated";
|
||||
public static final String EnclosingMethod = "EnclosingMethod";
|
||||
public static final String Exceptions = "Exceptions";
|
||||
public static final String InnerClasses = "InnerClasses";
|
||||
public static final String LineNumberTable = "LineNumberTable";
|
||||
public static final String LocalVariableTable = "LocalVariableTable";
|
||||
public static final String LocalVariableTypeTable = "LocalVariableTypeTable";
|
||||
public static final String RuntimeVisibleAnnotations = "RuntimeVisibleAnnotations";
|
||||
public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
|
||||
public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
|
||||
public static final String RuntimeInvisibleParameterAnnotations = "RuntimeInvisibleParameterAnnotations";
|
||||
public static final String Signature = "Signature";
|
||||
public static final String SourceDebugExtension = "SourceDebugExtension";
|
||||
public static final String SourceFile = "SourceFile";
|
||||
public static final String SourceID = "SourceID";
|
||||
public static final String StackMap = "StackMap";
|
||||
public static final String StackMapTable = "StackMapTable";
|
||||
public static final String Synthetic = "Synthetic";
|
||||
|
||||
// JSR 277/294
|
||||
public static final String Module = "Module";
|
||||
public static final String ModuleExportTable = "ModuleExportTable";
|
||||
public static final String ModuleMemberTable = "ModuleMemberTable";
|
||||
|
||||
public static class Factory {
|
||||
public Factory() {
|
||||
// defer init of standardAttributeClasses until after options set up
|
||||
}
|
||||
|
||||
public void setCompat(boolean compat) {
|
||||
this.compat = compat;
|
||||
}
|
||||
|
||||
public void setJSR277(boolean jsr277) {
|
||||
this.jsr277 = jsr277;
|
||||
}
|
||||
|
||||
public Attribute createAttribute(ClassReader cr, int name_index, byte[] data)
|
||||
throws IOException {
|
||||
if (standardAttributes == null)
|
||||
init();
|
||||
|
||||
ConstantPool cp = cr.getConstantPool();
|
||||
try {
|
||||
String name = cp.getUTF8Value(name_index);
|
||||
Class<? extends Attribute> attrClass = standardAttributes.get(name);
|
||||
if (attrClass != null) {
|
||||
try {
|
||||
Class<?>[] constrArgTypes = {ClassReader.class, int.class, int.class};
|
||||
Constructor<? extends Attribute> constr = attrClass.getDeclaredConstructor(constrArgTypes);
|
||||
return constr.newInstance(new Object[] { cr, name_index, data.length });
|
||||
} catch (Throwable t) {
|
||||
// fall through and use DefaultAttribute
|
||||
// t.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (ConstantPoolException e) {
|
||||
// fall through and use DefaultAttribute
|
||||
}
|
||||
return new DefaultAttribute(cr, name_index, data);
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
standardAttributes = new HashMap<String,Class<? extends Attribute>>();
|
||||
standardAttributes.put(AnnotationDefault, AnnotationDefault_attribute.class);
|
||||
standardAttributes.put(CharacterRangeTable, CharacterRangeTable_attribute.class);
|
||||
standardAttributes.put(Code, Code_attribute.class);
|
||||
standardAttributes.put(ConstantValue, ConstantValue_attribute.class);
|
||||
standardAttributes.put(Deprecated, Deprecated_attribute.class);
|
||||
standardAttributes.put(EnclosingMethod, EnclosingMethod_attribute.class);
|
||||
standardAttributes.put(Exceptions, Exceptions_attribute.class);
|
||||
standardAttributes.put(InnerClasses, InnerClasses_attribute.class);
|
||||
standardAttributes.put(LineNumberTable, LineNumberTable_attribute.class);
|
||||
standardAttributes.put(LocalVariableTable, LocalVariableTable_attribute.class);
|
||||
standardAttributes.put(LocalVariableTypeTable, LocalVariableTypeTable_attribute.class);
|
||||
|
||||
if (jsr277) {
|
||||
standardAttributes.put(Module, Module_attribute.class);
|
||||
standardAttributes.put(ModuleExportTable, ModuleExportTable_attribute.class);
|
||||
standardAttributes.put(ModuleMemberTable, ModuleMemberTable_attribute.class);
|
||||
}
|
||||
|
||||
if (!compat) { // old javap does not recognize recent attributes
|
||||
standardAttributes.put(CompilationID, CompilationID_attribute.class);
|
||||
standardAttributes.put(RuntimeInvisibleAnnotations, RuntimeInvisibleAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class);
|
||||
standardAttributes.put(RuntimeVisibleParameterAnnotations, RuntimeVisibleParameterAnnotations_attribute.class);
|
||||
standardAttributes.put(Signature, Signature_attribute.class);
|
||||
standardAttributes.put(SourceID, SourceID_attribute.class);
|
||||
}
|
||||
|
||||
standardAttributes.put(SourceDebugExtension, SourceDebugExtension_attribute.class);
|
||||
standardAttributes.put(SourceFile, SourceFile_attribute.class);
|
||||
standardAttributes.put(StackMap, StackMap_attribute.class);
|
||||
standardAttributes.put(StackMapTable, StackMapTable_attribute.class);
|
||||
standardAttributes.put(Synthetic, Synthetic_attribute.class);
|
||||
}
|
||||
|
||||
private Map<String,Class<? extends Attribute>> standardAttributes;
|
||||
private boolean compat; // don't support recent attrs in compatibility mode
|
||||
private boolean jsr277; // support new jsr277 attrs
|
||||
}
|
||||
|
||||
public static Attribute read(ClassReader cr) throws IOException {
|
||||
return cr.readAttribute();
|
||||
}
|
||||
|
||||
protected Attribute(int name_index, int length) {
|
||||
attribute_name_index = name_index;
|
||||
attribute_length = length;
|
||||
}
|
||||
|
||||
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(attribute_name_index);
|
||||
}
|
||||
|
||||
public abstract <R,D> R accept(Attribute.Visitor<R,D> visitor, D data);
|
||||
|
||||
public final int attribute_name_index;
|
||||
public final int attribute_length;
|
||||
|
||||
|
||||
public interface Visitor<R,P> {
|
||||
R visitDefault(DefaultAttribute attr, P p);
|
||||
R visitAnnotationDefault(AnnotationDefault_attribute attr, P p);
|
||||
R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p);
|
||||
R visitCode(Code_attribute attr, P p);
|
||||
R visitCompilationID(CompilationID_attribute attr, P p);
|
||||
R visitConstantValue(ConstantValue_attribute attr, P p);
|
||||
R visitDeprecated(Deprecated_attribute attr, P p);
|
||||
R visitEnclosingMethod(EnclosingMethod_attribute attr, P p);
|
||||
R visitExceptions(Exceptions_attribute attr, P p);
|
||||
R visitInnerClasses(InnerClasses_attribute attr, P p);
|
||||
R visitLineNumberTable(LineNumberTable_attribute attr, P p);
|
||||
R visitLocalVariableTable(LocalVariableTable_attribute attr, P p);
|
||||
R visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, P p);
|
||||
R visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, P p);
|
||||
R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p);
|
||||
R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p);
|
||||
R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p);
|
||||
R visitSignature(Signature_attribute attr, P p);
|
||||
R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p);
|
||||
R visitSourceFile(SourceFile_attribute attr, P p);
|
||||
R visitSourceID(SourceID_attribute attr, P p);
|
||||
R visitStackMap(StackMap_attribute attr, P p);
|
||||
R visitStackMapTable(StackMapTable_attribute attr, P p);
|
||||
R visitSynthetic(Synthetic_attribute attr, P p);
|
||||
|
||||
R visitModule(Module_attribute attr, P p);
|
||||
R visitModuleExportTable(ModuleExportTable_attribute attr, P p);
|
||||
R visitModuleMemberTable(ModuleMemberTable_attribute attr, P p);
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2008 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 com.sun.tools.classfile;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class AttributeException extends Exception {
|
||||
AttributeException() { }
|
||||
|
||||
AttributeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Attributes implements Iterable<Attribute> {
|
||||
Attributes(ClassReader cr) throws IOException {
|
||||
map = new HashMap<String,Attribute>();
|
||||
int attrs_count = cr.readUnsignedShort();
|
||||
attrs = new Attribute[attrs_count];
|
||||
for (int i = 0; i < attrs_count; i++) {
|
||||
Attribute attr = Attribute.read(cr);
|
||||
attrs[i] = attr;
|
||||
try {
|
||||
map.put(attr.getName(cr.getConstantPool()), attr);
|
||||
} catch (ConstantPoolException e) {
|
||||
// don't enter invalid names in map
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Attributes(ConstantPool constant_pool, Attribute[] attrs) {
|
||||
this.attrs = attrs;
|
||||
map = new HashMap<String,Attribute>();
|
||||
for (int i = 0; i < attrs.length; i++) {
|
||||
Attribute attr = attrs[i];
|
||||
try {
|
||||
map.put(attr.getName(constant_pool), attr);
|
||||
} catch (ConstantPoolException e) {
|
||||
// don't enter invalid names in map
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator<Attribute> iterator() {
|
||||
return Arrays.asList(attrs).iterator();
|
||||
}
|
||||
|
||||
public Attribute get(int index) {
|
||||
return attrs[index];
|
||||
}
|
||||
|
||||
public Attribute get(String name) {
|
||||
return map.get(name);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return attrs.length;
|
||||
}
|
||||
|
||||
public final Attribute[] attrs;
|
||||
public final Map<String, Attribute> map;
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class CharacterRangeTable_attribute extends Attribute {
|
||||
public static final int CRT_STATEMENT = 0x0001;
|
||||
public static final int CRT_BLOCK = 0x0002;
|
||||
public static final int CRT_ASSIGNMENT = 0x0004;
|
||||
public static final int CRT_FLOW_CONTROLLER = 0x0008;
|
||||
public static final int CRT_FLOW_TARGET = 0x0010;
|
||||
public static final int CRT_INVOKE = 0x0020;
|
||||
public static final int CRT_CREATE = 0x0040;
|
||||
public static final int CRT_BRANCH_TRUE = 0x0080;
|
||||
public static final int CRT_BRANCH_FALSE = 0x0100;
|
||||
|
||||
CharacterRangeTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
int character_range_table_length = cr.readUnsignedShort();
|
||||
character_range_table = new Entry[character_range_table_length];
|
||||
for (int i = 0; i < character_range_table_length; i++)
|
||||
character_range_table[i] = new Entry(cr);
|
||||
}
|
||||
|
||||
public CharacterRangeTable_attribute(ConstantPool constant_pool, Entry[] character_range_table)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.CharacterRangeTable), character_range_table);
|
||||
}
|
||||
|
||||
public CharacterRangeTable_attribute(int name_index, Entry[] character_range_table) {
|
||||
super(name_index, character_range_table.length * Entry.length());
|
||||
this.character_range_table = character_range_table;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitCharacterRangeTable(this, data);
|
||||
}
|
||||
|
||||
public final Entry[] character_range_table;
|
||||
|
||||
public static class Entry {
|
||||
Entry(ClassReader cr) throws IOException {
|
||||
start_pc = cr.readUnsignedShort();
|
||||
end_pc = cr.readUnsignedShort();
|
||||
character_range_start = cr.readInt();
|
||||
character_range_end = cr.readInt();
|
||||
flags = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public static int length() {
|
||||
return 14;
|
||||
}
|
||||
|
||||
public final int start_pc;
|
||||
public final int end_pc;
|
||||
public final int character_range_start;
|
||||
public final int character_range_end;
|
||||
public final int flags;
|
||||
};
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static com.sun.tools.classfile.AccessFlags.*;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.2.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ClassFile {
|
||||
public static ClassFile read(File file)
|
||||
throws IOException, ConstantPoolException {
|
||||
return read(file, new Attribute.Factory());
|
||||
}
|
||||
|
||||
public static ClassFile read(File file, Attribute.Factory attributeFactory)
|
||||
throws IOException, ConstantPoolException {
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
try {
|
||||
return new ClassFile(in, attributeFactory);
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ClassFile read(InputStream in)
|
||||
throws IOException, ConstantPoolException {
|
||||
return new ClassFile(in, new Attribute.Factory());
|
||||
}
|
||||
|
||||
public static ClassFile read(InputStream in, Attribute.Factory attributeFactory)
|
||||
throws IOException, ConstantPoolException {
|
||||
return new ClassFile(in, attributeFactory);
|
||||
}
|
||||
|
||||
ClassFile(InputStream in, Attribute.Factory attributeFactory) throws IOException, ConstantPoolException {
|
||||
ClassReader cr = new ClassReader(this, in, attributeFactory);
|
||||
magic = cr.readInt();
|
||||
minor_version = cr.readUnsignedShort();
|
||||
major_version = cr.readUnsignedShort();
|
||||
constant_pool = new ConstantPool(cr);
|
||||
access_flags = new AccessFlags(cr);
|
||||
this_class = cr.readUnsignedShort();
|
||||
super_class = cr.readUnsignedShort();
|
||||
|
||||
int interfaces_count = cr.readUnsignedShort();
|
||||
interfaces = new int[interfaces_count];
|
||||
for (int i = 0; i < interfaces_count; i++)
|
||||
interfaces[i] = cr.readUnsignedShort();
|
||||
|
||||
int fields_count = cr.readUnsignedShort();
|
||||
fields = new Field[fields_count];
|
||||
for (int i = 0; i < fields_count; i++)
|
||||
fields[i] = new Field(cr);
|
||||
|
||||
int methods_count = cr.readUnsignedShort();
|
||||
methods = new Method[methods_count];
|
||||
for (int i = 0; i < methods_count; i++)
|
||||
methods[i] = new Method(cr);
|
||||
|
||||
attributes = new Attributes(cr);
|
||||
}
|
||||
|
||||
public ClassFile(int magic, int minor_version, int major_version,
|
||||
ConstantPool constant_pool, AccessFlags access_flags,
|
||||
int this_class, int super_class, int[] interfaces,
|
||||
Field[] fields, Method[] methods, Attributes attributes) {
|
||||
this.magic = magic;
|
||||
this.minor_version = minor_version;
|
||||
this.major_version = major_version;
|
||||
this.constant_pool = constant_pool;
|
||||
this.access_flags = access_flags;
|
||||
this.this_class = this_class;
|
||||
this.super_class = super_class;
|
||||
this.interfaces = interfaces;
|
||||
this.fields = fields;
|
||||
this.methods = methods;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public String getName() throws ConstantPoolException {
|
||||
return constant_pool.getClassInfo(this_class).getName();
|
||||
}
|
||||
|
||||
public String getSuperclassName() throws ConstantPoolException {
|
||||
return constant_pool.getClassInfo(super_class).getName();
|
||||
}
|
||||
|
||||
public String getInterfaceName(int i) throws ConstantPoolException {
|
||||
return constant_pool.getClassInfo(interfaces[i]).getName();
|
||||
}
|
||||
|
||||
public Attribute getAttribute(String name) {
|
||||
return attributes.get(name);
|
||||
}
|
||||
|
||||
public boolean isClass() {
|
||||
return !isInterface();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return access_flags.is(ACC_INTERFACE);
|
||||
}
|
||||
|
||||
public final int magic;
|
||||
public final int minor_version;
|
||||
public final int major_version;
|
||||
public final ConstantPool constant_pool;
|
||||
public final AccessFlags access_flags;
|
||||
public final int this_class;
|
||||
public final int super_class;
|
||||
public final int[] interfaces;
|
||||
public final Field[] fields;
|
||||
public final Method[] methods;
|
||||
public final Attributes attributes;
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ClassReader {
|
||||
ClassReader(ClassFile classFile, InputStream in, Attribute.Factory attributeFactory) throws IOException {
|
||||
// null checks
|
||||
classFile.getClass();
|
||||
attributeFactory.getClass();
|
||||
|
||||
this.classFile = classFile;
|
||||
this.in = new DataInputStream(new BufferedInputStream(in));
|
||||
this.attributeFactory = attributeFactory;
|
||||
}
|
||||
|
||||
ClassFile getClassFile() {
|
||||
return classFile;
|
||||
}
|
||||
|
||||
ConstantPool getConstantPool() {
|
||||
return classFile.constant_pool;
|
||||
}
|
||||
|
||||
public Attribute readAttribute() throws IOException {
|
||||
int name_index = readUnsignedShort();
|
||||
int length = readInt();
|
||||
byte[] data = new byte[length];
|
||||
readFully(data);
|
||||
|
||||
DataInputStream prev = in;
|
||||
in = new DataInputStream(new ByteArrayInputStream(data));
|
||||
try {
|
||||
return attributeFactory.createAttribute(this, name_index, data);
|
||||
} finally {
|
||||
in = prev;
|
||||
}
|
||||
}
|
||||
|
||||
public void readFully(byte[] b) throws IOException {
|
||||
in.readFully(b);
|
||||
}
|
||||
|
||||
public int readUnsignedByte() throws IOException {
|
||||
return in.readUnsignedByte();
|
||||
}
|
||||
|
||||
public int readUnsignedShort() throws IOException {
|
||||
return in.readUnsignedShort();
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
return in.readInt();
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
return in.readLong();
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
return in.readFloat();
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
return in.readDouble();
|
||||
}
|
||||
|
||||
public String readUTF() throws IOException {
|
||||
return in.readUTF();
|
||||
}
|
||||
|
||||
private DataInputStream in;
|
||||
private ClassFile classFile;
|
||||
private Attribute.Factory attributeFactory;
|
||||
}
|
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright 2008 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 com.sun.tools.classfile;
|
||||
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Double_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Fieldref_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Float_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Integer_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_InterfaceMethodref_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Long_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_String_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
|
||||
import com.sun.tools.classfile.ConstantPool.CPInfo;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Rewrites a class file using a map of translations.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ClassTranslator
|
||||
implements ConstantPool.Visitor<ConstantPool.CPInfo,Map<Object,Object>> {
|
||||
/**
|
||||
* Create a new ClassFile from {@code cf}, such that for all entries
|
||||
* {@code k -\> v} in {@code translations},
|
||||
* each occurrence of {@code k} in {@code cf} will be replaced by {@code v}.
|
||||
* in
|
||||
* @param cf the class file to be processed
|
||||
* @param translations the set of translations to be applied
|
||||
* @return a copy of {@code} with the values in {@code translations} substituted
|
||||
*/
|
||||
public ClassFile translate(ClassFile cf, Map<Object,Object> translations) {
|
||||
ClassFile cf2 = (ClassFile) translations.get(cf);
|
||||
if (cf2 == null) {
|
||||
ConstantPool constant_pool2 = translate(cf.constant_pool, translations);
|
||||
Field[] fields2 = translate(cf.fields, cf.constant_pool, translations);
|
||||
Method[] methods2 = translateMethods(cf.methods, cf.constant_pool, translations);
|
||||
Attributes attributes2 = translateAttributes(cf.attributes, cf.constant_pool,
|
||||
translations);
|
||||
|
||||
if (constant_pool2 == cf.constant_pool &&
|
||||
fields2 == cf.fields &&
|
||||
methods2 == cf.methods &&
|
||||
attributes2 == cf.attributes)
|
||||
cf2 = cf;
|
||||
else
|
||||
cf2 = new ClassFile(
|
||||
cf.magic,
|
||||
cf.minor_version,
|
||||
cf.major_version,
|
||||
constant_pool2,
|
||||
cf.access_flags,
|
||||
cf.this_class,
|
||||
cf.super_class,
|
||||
cf.interfaces,
|
||||
fields2,
|
||||
methods2,
|
||||
attributes2);
|
||||
translations.put(cf, cf2);
|
||||
}
|
||||
return cf2;
|
||||
}
|
||||
|
||||
ConstantPool translate(ConstantPool cp, Map<Object,Object> translations) {
|
||||
ConstantPool cp2 = (ConstantPool) translations.get(cp);
|
||||
if (cp2 == null) {
|
||||
ConstantPool.CPInfo[] pool2 = new ConstantPool.CPInfo[cp.size()];
|
||||
boolean eq = true;
|
||||
for (int i = 0; i < cp.size(); i++) {
|
||||
ConstantPool.CPInfo cpInfo;
|
||||
try {
|
||||
cpInfo = cp.get(i);
|
||||
} catch (ConstantPool.InvalidIndex e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
ConstantPool.CPInfo cpInfo2 = translate(cpInfo, translations);
|
||||
eq &= (cpInfo == cpInfo2);
|
||||
pool2[i] = cpInfo2;
|
||||
if (cpInfo.getTag() != cpInfo2.getTag())
|
||||
throw new IllegalStateException();
|
||||
switch (cpInfo.getTag()) {
|
||||
case ConstantPool.CONSTANT_Double:
|
||||
case ConstantPool.CONSTANT_Long:
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (eq)
|
||||
cp2 = cp;
|
||||
else
|
||||
cp2 = new ConstantPool(pool2);
|
||||
|
||||
translations.put(cp, cp2);
|
||||
}
|
||||
return cp2;
|
||||
}
|
||||
|
||||
ConstantPool.CPInfo translate(ConstantPool.CPInfo cpInfo, Map<Object,Object> translations) {
|
||||
ConstantPool.CPInfo cpInfo2 = (ConstantPool.CPInfo) translations.get(cpInfo);
|
||||
if (cpInfo2 == null) {
|
||||
cpInfo2 = cpInfo.accept(this, translations);
|
||||
translations.put(cpInfo, cpInfo2);
|
||||
}
|
||||
return cpInfo2;
|
||||
}
|
||||
|
||||
Field[] translate(Field[] fields, ConstantPool constant_pool, Map<Object,Object> translations) {
|
||||
Field[] fields2 = (Field[]) translations.get(fields);
|
||||
if (fields2 == null) {
|
||||
fields2 = new Field[fields.length];
|
||||
for (int i = 0; i < fields.length; i++)
|
||||
fields2[i] = translate(fields[i], constant_pool, translations);
|
||||
if (equal(fields, fields2))
|
||||
fields2 = fields;
|
||||
translations.put(fields, fields2);
|
||||
}
|
||||
return fields2;
|
||||
}
|
||||
|
||||
Field translate(Field field, ConstantPool constant_pool, Map<Object,Object> translations) {
|
||||
Field field2 = (Field) translations.get(field);
|
||||
if (field2 == null) {
|
||||
Attributes attributes2 = translateAttributes(field.attributes, constant_pool,
|
||||
translations);
|
||||
|
||||
if (attributes2 == field.attributes)
|
||||
field2 = field;
|
||||
else
|
||||
field2 = new Field(
|
||||
field.access_flags,
|
||||
field.name_index,
|
||||
field.descriptor,
|
||||
attributes2);
|
||||
translations.put(field, field2);
|
||||
}
|
||||
return field2;
|
||||
}
|
||||
|
||||
Method[] translateMethods(Method[] methods, ConstantPool constant_pool, Map<Object,Object> translations) {
|
||||
Method[] methods2 = (Method[]) translations.get(methods);
|
||||
if (methods2 == null) {
|
||||
methods2 = new Method[methods.length];
|
||||
for (int i = 0; i < methods.length; i++)
|
||||
methods2[i] = translate(methods[i], constant_pool, translations);
|
||||
if (equal(methods, methods2))
|
||||
methods2 = methods;
|
||||
translations.put(methods, methods2);
|
||||
}
|
||||
return methods2;
|
||||
}
|
||||
|
||||
Method translate(Method method, ConstantPool constant_pool, Map<Object,Object> translations) {
|
||||
Method method2 = (Method) translations.get(method);
|
||||
if (method2 == null) {
|
||||
Attributes attributes2 = translateAttributes(method.attributes, constant_pool,
|
||||
translations);
|
||||
|
||||
if (attributes2 == method.attributes)
|
||||
method2 = method;
|
||||
else
|
||||
method2 = new Method(
|
||||
method.access_flags,
|
||||
method.name_index,
|
||||
method.descriptor,
|
||||
attributes2);
|
||||
translations.put(method, method2);
|
||||
}
|
||||
return method2;
|
||||
}
|
||||
|
||||
Attributes translateAttributes(Attributes attributes,
|
||||
ConstantPool constant_pool, Map<Object,Object> translations) {
|
||||
Attributes attributes2 = (Attributes) translations.get(attributes);
|
||||
if (attributes2 == null) {
|
||||
Attribute[] attrArray2 = new Attribute[attributes.size()];
|
||||
ConstantPool constant_pool2 = translate(constant_pool, translations);
|
||||
boolean attrsEqual = true;
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
Attribute attr = attributes.get(i);
|
||||
Attribute attr2 = translate(attr, translations);
|
||||
if (attr2 != attr)
|
||||
attrsEqual = false;
|
||||
attrArray2[i] = attr2;
|
||||
}
|
||||
if ((constant_pool2 == constant_pool) && attrsEqual)
|
||||
attributes2 = attributes;
|
||||
else
|
||||
attributes2 = new Attributes(constant_pool2, attrArray2);
|
||||
translations.put(attributes, attributes2);
|
||||
}
|
||||
return attributes2;
|
||||
}
|
||||
|
||||
Attribute translate(Attribute attribute, Map<Object,Object> translations) {
|
||||
Attribute attribute2 = (Attribute) translations.get(attribute);
|
||||
if (attribute2 == null) {
|
||||
attribute2 = attribute; // don't support translation within attributes yet
|
||||
// (what about Code attribute)
|
||||
translations.put(attribute, attribute2);
|
||||
}
|
||||
return attribute2;
|
||||
}
|
||||
|
||||
private static <T> boolean equal(T[] a1, T[] a2) {
|
||||
if (a1 == null || a2 == null)
|
||||
return (a1 == a2);
|
||||
if (a1.length != a2.length)
|
||||
return false;
|
||||
for (int i = 0; i < a1.length; i++) {
|
||||
if (a1[i] != a2[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public CPInfo visitClass(CONSTANT_Class_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_Class_info info2 = (CONSTANT_Class_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
ConstantPool cp2 = translate(info.cp, translations);
|
||||
if (cp2 == info.cp)
|
||||
info2 = info;
|
||||
else
|
||||
info2 = new CONSTANT_Class_info(cp2, info.name_index);
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitDouble(CONSTANT_Double_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_Double_info info2 = (CONSTANT_Double_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
info2 = info;
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitFieldref(CONSTANT_Fieldref_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_Fieldref_info info2 = (CONSTANT_Fieldref_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
ConstantPool cp2 = translate(info.cp, translations);
|
||||
if (cp2 == info.cp)
|
||||
info2 = info;
|
||||
else
|
||||
info2 = new CONSTANT_Fieldref_info(cp2, info.class_index, info.name_and_type_index);
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitFloat(CONSTANT_Float_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_Float_info info2 = (CONSTANT_Float_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
info2 = info;
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitInteger(CONSTANT_Integer_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_Integer_info info2 = (CONSTANT_Integer_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
info2 = info;
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_InterfaceMethodref_info info2 = (CONSTANT_InterfaceMethodref_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
ConstantPool cp2 = translate(info.cp, translations);
|
||||
if (cp2 == info.cp)
|
||||
info2 = info;
|
||||
else
|
||||
info2 = new CONSTANT_InterfaceMethodref_info(cp2, info.class_index, info.name_and_type_index);
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitLong(CONSTANT_Long_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_Long_info info2 = (CONSTANT_Long_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
info2 = info;
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitNameAndType(CONSTANT_NameAndType_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_NameAndType_info info2 = (CONSTANT_NameAndType_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
ConstantPool cp2 = translate(info.cp, translations);
|
||||
if (cp2 == info.cp)
|
||||
info2 = info;
|
||||
else
|
||||
info2 = new CONSTANT_NameAndType_info(cp2, info.name_index, info.type_index);
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitMethodref(CONSTANT_Methodref_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_Methodref_info info2 = (CONSTANT_Methodref_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
ConstantPool cp2 = translate(info.cp, translations);
|
||||
if (cp2 == info.cp)
|
||||
info2 = info;
|
||||
else
|
||||
info2 = new CONSTANT_Methodref_info(cp2, info.class_index, info.name_and_type_index);
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitString(CONSTANT_String_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_String_info info2 = (CONSTANT_String_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
ConstantPool cp2 = translate(info.cp, translations);
|
||||
if (cp2 == info.cp)
|
||||
info2 = info;
|
||||
else
|
||||
info2 = new CONSTANT_String_info(cp2, info.string_index);
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public CPInfo visitUtf8(CONSTANT_Utf8_info info, Map<Object, Object> translations) {
|
||||
CONSTANT_Utf8_info info2 = (CONSTANT_Utf8_info) translations.get(info);
|
||||
if (info2 == null) {
|
||||
info2 = info;
|
||||
translations.put(info, info2);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,689 @@
|
||||
/*
|
||||
* Copyright 2008 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import static com.sun.tools.classfile.Annotation.*;
|
||||
import static com.sun.tools.classfile.ConstantPool.*;
|
||||
import static com.sun.tools.classfile.StackMapTable_attribute.*;
|
||||
import static com.sun.tools.classfile.StackMapTable_attribute.verification_type_info.*;
|
||||
|
||||
/**
|
||||
* Write a ClassFile data structure to a file or stream.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ClassWriter {
|
||||
public ClassWriter() {
|
||||
attributeWriter = new AttributeWriter();
|
||||
constantPoolWriter = new ConstantPoolWriter();
|
||||
out = new ClassOutputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a ClassFile data structure to a file.
|
||||
*/
|
||||
public void write(ClassFile classFile, File f) throws IOException {
|
||||
FileOutputStream f_out = new FileOutputStream(f);
|
||||
try {
|
||||
write(classFile, f_out);
|
||||
} finally {
|
||||
f_out.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a ClassFile data structure to a stream.
|
||||
*/
|
||||
public void write(ClassFile classFile, OutputStream s) throws IOException {
|
||||
this.classFile = classFile;
|
||||
out.reset();
|
||||
write();
|
||||
out.writeTo(s);
|
||||
}
|
||||
|
||||
protected void write() throws IOException {
|
||||
writeHeader();
|
||||
writeConstantPool();
|
||||
writeAccessFlags(classFile.access_flags);
|
||||
writeClassInfo();
|
||||
writeFields();
|
||||
writeMethods();
|
||||
writeAttributes(classFile.attributes);
|
||||
}
|
||||
|
||||
protected void writeHeader() {
|
||||
out.writeInt(classFile.magic);
|
||||
out.writeShort(classFile.minor_version);
|
||||
out.writeShort(classFile.major_version);
|
||||
}
|
||||
|
||||
protected void writeAccessFlags(AccessFlags flags) {
|
||||
out.writeShort(flags.flags);
|
||||
}
|
||||
|
||||
protected void writeAttributes(Attributes attributes) {
|
||||
int size = attributes.size();
|
||||
out.writeShort(size);
|
||||
for (Attribute attr: attributes)
|
||||
attributeWriter.write(attr, out);
|
||||
}
|
||||
|
||||
protected void writeClassInfo() {
|
||||
out.writeShort(classFile.this_class);
|
||||
out.writeShort(classFile.super_class);
|
||||
int[] interfaces = classFile.interfaces;
|
||||
out.writeShort(interfaces.length);
|
||||
for (int i: interfaces)
|
||||
out.writeShort(i);
|
||||
}
|
||||
|
||||
protected void writeDescriptor(Descriptor d) {
|
||||
out.writeShort(d.index);
|
||||
}
|
||||
|
||||
protected void writeConstantPool() {
|
||||
ConstantPool pool = classFile.constant_pool;
|
||||
int size = pool.size();
|
||||
out.writeShort(size);
|
||||
try {
|
||||
for (int i = 1; i < size; ) {
|
||||
i += constantPoolWriter.write(pool.get(i), out);
|
||||
}
|
||||
} catch (ConstantPoolException e) {
|
||||
throw new Error(e); // ??
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeFields() throws IOException {
|
||||
Field[] fields = classFile.fields;
|
||||
out.writeShort(fields.length);
|
||||
for (Field f: fields)
|
||||
writeField(f);
|
||||
}
|
||||
|
||||
protected void writeField(Field f) throws IOException {
|
||||
writeAccessFlags(f.access_flags);
|
||||
out.writeShort(f.name_index);
|
||||
writeDescriptor(f.descriptor);
|
||||
writeAttributes(f.attributes);
|
||||
}
|
||||
|
||||
protected void writeMethods() throws IOException {
|
||||
Method[] methods = classFile.methods;
|
||||
out.writeShort(methods.length);
|
||||
for (Method m: methods) {
|
||||
writeMethod(m);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeMethod(Method m) throws IOException {
|
||||
writeAccessFlags(m.access_flags);
|
||||
out.writeShort(m.name_index);
|
||||
writeDescriptor(m.descriptor);
|
||||
writeAttributes(m.attributes);
|
||||
}
|
||||
|
||||
protected ClassFile classFile;
|
||||
protected ClassOutputStream out;
|
||||
protected AttributeWriter attributeWriter;
|
||||
protected ConstantPoolWriter constantPoolWriter;
|
||||
|
||||
/**
|
||||
* Subtype of ByteArrayOutputStream with the convenience methods of
|
||||
* a DataOutputStream. Since ByteArrayOutputStream does not throw
|
||||
* IOException, there are no exceptions from the additional
|
||||
* convenience methods either,
|
||||
*/
|
||||
protected static class ClassOutputStream extends ByteArrayOutputStream {
|
||||
public ClassOutputStream() {
|
||||
d = new DataOutputStream(this);
|
||||
}
|
||||
|
||||
public void writeByte(int value) {
|
||||
try {
|
||||
d.writeByte(value);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeShort(int value) {
|
||||
try {
|
||||
d.writeShort(value);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeInt(int value) {
|
||||
try {
|
||||
d.writeInt(value);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeLong(long value) {
|
||||
try {
|
||||
d.writeLong(value);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeFloat(float value) {
|
||||
try {
|
||||
d.writeFloat(value);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeDouble(double value) {
|
||||
try {
|
||||
d.writeDouble(value);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeUTF(String value) {
|
||||
try {
|
||||
d.writeUTF(value);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTo(ClassOutputStream s) {
|
||||
try {
|
||||
super.writeTo(s);
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
private DataOutputStream d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writer for the entries in the constant pool.
|
||||
*/
|
||||
protected static class ConstantPoolWriter
|
||||
implements ConstantPool.Visitor<Integer,ClassOutputStream> {
|
||||
protected int write(CPInfo info, ClassOutputStream out) {
|
||||
out.writeByte(info.getTag());
|
||||
return info.accept(this, out);
|
||||
}
|
||||
|
||||
public Integer visitClass(CONSTANT_Class_info info, ClassOutputStream out) {
|
||||
out.writeShort(info.name_index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitDouble(CONSTANT_Double_info info, ClassOutputStream out) {
|
||||
out.writeDouble(info.value);
|
||||
return 2;
|
||||
}
|
||||
|
||||
public Integer visitFieldref(CONSTANT_Fieldref_info info, ClassOutputStream out) {
|
||||
writeRef(info, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitFloat(CONSTANT_Float_info info, ClassOutputStream out) {
|
||||
out.writeFloat(info.value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitInteger(CONSTANT_Integer_info info, ClassOutputStream out) {
|
||||
out.writeInt(info.value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, ClassOutputStream out) {
|
||||
writeRef(info, out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitLong(CONSTANT_Long_info info, ClassOutputStream out) {
|
||||
out.writeLong(info.value);
|
||||
return 2;
|
||||
}
|
||||
|
||||
public Integer visitNameAndType(CONSTANT_NameAndType_info info, ClassOutputStream out) {
|
||||
out.writeShort(info.name_index);
|
||||
out.writeShort(info.type_index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitMethodref(CONSTANT_Methodref_info info, ClassOutputStream out) {
|
||||
return writeRef(info, out);
|
||||
}
|
||||
|
||||
public Integer visitString(CONSTANT_String_info info, ClassOutputStream out) {
|
||||
out.writeShort(info.string_index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitUtf8(CONSTANT_Utf8_info info, ClassOutputStream out) {
|
||||
out.writeUTF(info.value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected Integer writeRef(CPRefInfo info, ClassOutputStream out) {
|
||||
out.writeShort(info.class_index);
|
||||
out.writeShort(info.name_and_type_index);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writer for the different types of attribute.
|
||||
*/
|
||||
protected static class AttributeWriter implements Attribute.Visitor<Void,ClassOutputStream> {
|
||||
public void write(Attributes attributes, ClassOutputStream out) {
|
||||
int size = attributes.size();
|
||||
out.writeShort(size);
|
||||
for (Attribute a: attributes)
|
||||
write(a, out);
|
||||
}
|
||||
|
||||
// Note: due to the use of shared resources, this method is not reentrant.
|
||||
public void write(Attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.attribute_name_index);
|
||||
sharedOut.reset();
|
||||
attr.accept(this, sharedOut);
|
||||
out.writeInt(sharedOut.size());
|
||||
sharedOut.writeTo(out);
|
||||
}
|
||||
|
||||
protected ClassOutputStream sharedOut = new ClassOutputStream();
|
||||
protected AnnotationWriter annotationWriter = new AnnotationWriter();
|
||||
|
||||
public Void visitDefault(DefaultAttribute attr, ClassOutputStream out) {
|
||||
out.write(attr.info, 0, attr.info.length);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitAnnotationDefault(AnnotationDefault_attribute attr, ClassOutputStream out) {
|
||||
annotationWriter.write(attr.default_value, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.character_range_table.length);
|
||||
for (CharacterRangeTable_attribute.Entry e: attr.character_range_table)
|
||||
writeCharacterRangeTableEntry(e, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void writeCharacterRangeTableEntry(CharacterRangeTable_attribute.Entry entry, ClassOutputStream out) {
|
||||
out.writeShort(entry.start_pc);
|
||||
out.writeShort(entry.end_pc);
|
||||
out.writeInt(entry.character_range_start);
|
||||
out.writeInt(entry.character_range_end);
|
||||
out.writeShort(entry.flags);
|
||||
}
|
||||
|
||||
public Void visitCode(Code_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.max_stack);
|
||||
out.writeShort(attr.max_locals);
|
||||
out.writeInt(attr.code.length);
|
||||
out.write(attr.code, 0, attr.code.length);
|
||||
out.writeShort(attr.exception_table.length);
|
||||
for (Code_attribute.Exception_data e: attr.exception_table)
|
||||
writeExceptionTableEntry(e, out);
|
||||
new AttributeWriter().write(attr.attributes, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void writeExceptionTableEntry(Code_attribute.Exception_data exception_data, ClassOutputStream out) {
|
||||
out.writeShort(exception_data.start_pc);
|
||||
out.writeShort(exception_data.end_pc);
|
||||
out.writeShort(exception_data.handler_pc);
|
||||
out.writeShort(exception_data.catch_type);
|
||||
}
|
||||
|
||||
public Void visitCompilationID(CompilationID_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.compilationID_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitConstantValue(ConstantValue_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.constantvalue_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitDeprecated(Deprecated_attribute attr, ClassOutputStream out) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitEnclosingMethod(EnclosingMethod_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.class_index);
|
||||
out.writeShort(attr.method_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitExceptions(Exceptions_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.exception_index_table.length);
|
||||
for (int i: attr.exception_index_table)
|
||||
out.writeShort(i);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitInnerClasses(InnerClasses_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.classes.length);
|
||||
for (InnerClasses_attribute.Info info: attr.classes)
|
||||
writeInnerClassesInfo(info, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void writeInnerClassesInfo(InnerClasses_attribute.Info info, ClassOutputStream out) {
|
||||
out.writeShort(info.inner_class_info_index);
|
||||
out.writeShort(info.outer_class_info_index);
|
||||
out.writeShort(info.inner_name_index);
|
||||
writeAccessFlags(info.inner_class_access_flags, out);
|
||||
}
|
||||
|
||||
public Void visitLineNumberTable(LineNumberTable_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.line_number_table.length);
|
||||
for (LineNumberTable_attribute.Entry e: attr.line_number_table)
|
||||
writeLineNumberTableEntry(e, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void writeLineNumberTableEntry(LineNumberTable_attribute.Entry entry, ClassOutputStream out) {
|
||||
out.writeShort(entry.start_pc);
|
||||
out.writeShort(entry.line_number);
|
||||
}
|
||||
|
||||
public Void visitLocalVariableTable(LocalVariableTable_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.local_variable_table.length);
|
||||
for (LocalVariableTable_attribute.Entry e: attr.local_variable_table)
|
||||
writeLocalVariableTableEntry(e, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void writeLocalVariableTableEntry(LocalVariableTable_attribute.Entry entry, ClassOutputStream out) {
|
||||
out.writeShort(entry.start_pc);
|
||||
out.writeShort(entry.length);
|
||||
out.writeShort(entry.name_index);
|
||||
out.writeShort(entry.descriptor_index);
|
||||
out.writeShort(entry.index);
|
||||
}
|
||||
|
||||
public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, ClassOutputStream out) {
|
||||
out.writeByte(attr.local_variable_table.length);
|
||||
for (LocalVariableTypeTable_attribute.Entry e: attr.local_variable_table)
|
||||
writeLocalVariableTypeTableEntry(e, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void writeLocalVariableTypeTableEntry(LocalVariableTypeTable_attribute.Entry entry, ClassOutputStream out) {
|
||||
out.writeShort(entry.start_pc);
|
||||
out.writeShort(entry.length);
|
||||
out.writeShort(entry.name_index);
|
||||
out.writeShort(entry.signature_index);
|
||||
out.writeShort(entry.index);
|
||||
}
|
||||
|
||||
public Void visitModule(Module_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.module_name);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitModuleExportTable(ModuleExportTable_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.export_type_table.length);
|
||||
for (int i: attr.export_type_table)
|
||||
out.writeShort(i);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitModuleMemberTable(ModuleMemberTable_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.package_member_table.length);
|
||||
for (int i: attr.package_member_table)
|
||||
out.writeShort(i);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, ClassOutputStream out) {
|
||||
annotationWriter.write(attr.annotations, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, ClassOutputStream out) {
|
||||
annotationWriter.write(attr.annotations, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
|
||||
out.writeByte(attr.parameter_annotations.length);
|
||||
for (Annotation[] annos: attr.parameter_annotations)
|
||||
annotationWriter.write(annos, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
|
||||
out.writeByte(attr.parameter_annotations.length);
|
||||
for (Annotation[] annos: attr.parameter_annotations)
|
||||
annotationWriter.write(annos, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitSignature(Signature_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.signature_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, ClassOutputStream out) {
|
||||
out.write(attr.debug_extension, 0, attr.debug_extension.length);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitSourceFile(SourceFile_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.sourcefile_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitSourceID(SourceID_attribute attr, ClassOutputStream out) {
|
||||
out.writeShort(attr.sourceID_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitStackMap(StackMap_attribute attr, ClassOutputStream out) {
|
||||
if (stackMapWriter == null)
|
||||
stackMapWriter = new StackMapTableWriter();
|
||||
|
||||
out.writeShort(attr.entries.length);
|
||||
for (stack_map_frame f: attr.entries)
|
||||
stackMapWriter.write(f, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitStackMapTable(StackMapTable_attribute attr, ClassOutputStream out) {
|
||||
if (stackMapWriter == null)
|
||||
stackMapWriter = new StackMapTableWriter();
|
||||
|
||||
out.writeShort(attr.entries.length);
|
||||
for (stack_map_frame f: attr.entries)
|
||||
stackMapWriter.write(f, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitSynthetic(Synthetic_attribute attr, ClassOutputStream out) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void writeAccessFlags(AccessFlags flags, ClassOutputStream p) {
|
||||
sharedOut.writeShort(flags.flags);
|
||||
}
|
||||
|
||||
protected StackMapTableWriter stackMapWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writer for the frames of StackMap and StackMapTable attributes.
|
||||
*/
|
||||
protected static class StackMapTableWriter
|
||||
implements stack_map_frame.Visitor<Void,ClassOutputStream> {
|
||||
|
||||
public void write(stack_map_frame frame, ClassOutputStream out) {
|
||||
out.write(frame.frame_type);
|
||||
frame.accept(this, out);
|
||||
}
|
||||
|
||||
public Void visit_same_frame(same_frame frame, ClassOutputStream p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, ClassOutputStream out) {
|
||||
writeVerificationTypeInfo(frame.stack[0], out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, ClassOutputStream out) {
|
||||
out.writeShort(frame.offset_delta);
|
||||
writeVerificationTypeInfo(frame.stack[0], out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_chop_frame(chop_frame frame, ClassOutputStream out) {
|
||||
out.writeShort(frame.offset_delta);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_same_frame_extended(same_frame_extended frame, ClassOutputStream out) {
|
||||
out.writeShort(frame.offset_delta);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_append_frame(append_frame frame, ClassOutputStream out) {
|
||||
out.writeShort(frame.offset_delta);
|
||||
for (verification_type_info l: frame.locals)
|
||||
writeVerificationTypeInfo(l, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_full_frame(full_frame frame, ClassOutputStream out) {
|
||||
out.writeShort(frame.offset_delta);
|
||||
out.writeShort(frame.locals.length);
|
||||
for (verification_type_info l: frame.locals)
|
||||
writeVerificationTypeInfo(l, out);
|
||||
out.writeShort(frame.stack.length);
|
||||
for (verification_type_info s: frame.stack)
|
||||
writeVerificationTypeInfo(s, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void writeVerificationTypeInfo(verification_type_info info,
|
||||
ClassOutputStream out) {
|
||||
out.write(info.tag);
|
||||
switch (info.tag) {
|
||||
case ITEM_Top:
|
||||
case ITEM_Integer:
|
||||
case ITEM_Float:
|
||||
case ITEM_Long:
|
||||
case ITEM_Double:
|
||||
case ITEM_Null:
|
||||
case ITEM_UninitializedThis:
|
||||
break;
|
||||
|
||||
case ITEM_Object:
|
||||
Object_variable_info o = (Object_variable_info) info;
|
||||
out.writeShort(o.cpool_index);
|
||||
break;
|
||||
|
||||
case ITEM_Uninitialized:
|
||||
Uninitialized_variable_info u = (Uninitialized_variable_info) info;
|
||||
out.writeShort(u.offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writer for annotations and the values they contain.
|
||||
*/
|
||||
protected static class AnnotationWriter
|
||||
implements Annotation.element_value.Visitor<Void,ClassOutputStream> {
|
||||
public void write(Annotation[] annos, ClassOutputStream out) {
|
||||
out.writeShort(annos.length);
|
||||
for (Annotation anno: annos)
|
||||
write(anno, out);
|
||||
}
|
||||
|
||||
public void write(Annotation anno, ClassOutputStream out) {
|
||||
out.writeShort(anno.type_index);
|
||||
out.writeShort(anno.element_value_pairs.length);
|
||||
for (element_value_pair p: anno.element_value_pairs)
|
||||
write(p, out);
|
||||
}
|
||||
|
||||
public void write(element_value_pair pair, ClassOutputStream out) {
|
||||
out.writeShort(pair.element_name_index);
|
||||
write(pair.value, out);
|
||||
}
|
||||
|
||||
public void write(element_value ev, ClassOutputStream out) {
|
||||
out.writeByte(ev.tag);
|
||||
ev.accept(this, out);
|
||||
}
|
||||
|
||||
public Void visitPrimitive(Primitive_element_value ev, ClassOutputStream out) {
|
||||
out.writeShort(ev.const_value_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitEnum(Enum_element_value ev, ClassOutputStream out) {
|
||||
out.writeShort(ev.type_name_index);
|
||||
out.writeShort(ev.const_name_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitClass(Class_element_value ev, ClassOutputStream out) {
|
||||
out.writeShort(ev.class_info_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitAnnotation(Annotation_element_value ev, ClassOutputStream out) {
|
||||
write(ev.annotation_value, out);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitArray(Array_element_value ev, ClassOutputStream out) {
|
||||
out.writeShort(ev.num_values);
|
||||
for (element_value v: ev.values)
|
||||
write(v, out);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.3.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Code_attribute extends Attribute {
|
||||
public class InvalidIndex extends AttributeException {
|
||||
InvalidIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
// i18n
|
||||
return "invalid index " + index + " in Code attribute";
|
||||
}
|
||||
|
||||
public final int index;
|
||||
}
|
||||
|
||||
Code_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, ConstantPoolException {
|
||||
super(name_index, length);
|
||||
max_stack = cr.readUnsignedShort();
|
||||
max_locals = cr.readUnsignedShort();
|
||||
code_length = cr.readInt();
|
||||
code = new byte[code_length];
|
||||
cr.readFully(code);
|
||||
exception_table_langth = cr.readUnsignedShort();
|
||||
exception_table = new Exception_data[exception_table_langth];
|
||||
for (int i = 0; i < exception_table_langth; i++)
|
||||
exception_table[i] = new Exception_data(cr);
|
||||
attributes = new Attributes(cr);
|
||||
}
|
||||
|
||||
public int getByte(int offset) throws InvalidIndex {
|
||||
if (offset < 0 || offset >= code.length)
|
||||
throw new InvalidIndex(offset);
|
||||
return code[offset];
|
||||
}
|
||||
|
||||
public int getUnsignedByte(int offset) throws InvalidIndex {
|
||||
if (offset < 0 || offset >= code.length)
|
||||
throw new InvalidIndex(offset);
|
||||
return code[offset] & 0xff;
|
||||
}
|
||||
|
||||
public int getShort(int offset) throws InvalidIndex {
|
||||
if (offset < 0 || offset + 1 >= code.length)
|
||||
throw new InvalidIndex(offset);
|
||||
return (code[offset] << 8) | (code[offset + 1] & 0xFF);
|
||||
}
|
||||
|
||||
public int getUnsignedShort(int offset) throws InvalidIndex {
|
||||
if (offset < 0 || offset + 1 >= code.length)
|
||||
throw new InvalidIndex(offset);
|
||||
return ((code[offset] << 8) | (code[offset + 1] & 0xFF)) & 0xFFFF;
|
||||
}
|
||||
|
||||
public int getInt(int offset) throws InvalidIndex {
|
||||
if (offset < 0 || offset + 3 >= code.length)
|
||||
throw new InvalidIndex(offset);
|
||||
return (getShort(offset) << 16) | (getShort(offset + 2) & 0xFFFF);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitCode(this, data);
|
||||
}
|
||||
|
||||
public final int max_stack;
|
||||
public final int max_locals;
|
||||
public final int code_length;
|
||||
public final byte[] code;
|
||||
public final int exception_table_langth;
|
||||
public final Exception_data[] exception_table;
|
||||
public final Attributes attributes;
|
||||
|
||||
public class Exception_data {
|
||||
Exception_data(ClassReader cr) throws IOException {
|
||||
start_pc = cr.readUnsignedShort();
|
||||
end_pc = cr.readUnsignedShort();
|
||||
handler_pc = cr.readUnsignedShort();
|
||||
catch_type = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public final int start_pc;
|
||||
public final int end_pc;
|
||||
public final int handler_pc;
|
||||
public final int catch_type;
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2008 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class CompilationID_attribute extends Attribute {
|
||||
|
||||
CompilationID_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
compilationID_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public CompilationID_attribute(ConstantPool constant_pool, int compilationID_index)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.CompilationID), compilationID_index);
|
||||
}
|
||||
|
||||
public CompilationID_attribute(int name_index, int compilationID_index) {
|
||||
super(name_index, 2);
|
||||
this.compilationID_index = compilationID_index;
|
||||
}
|
||||
|
||||
String getCompilationID(ConstantPool constant_pool)
|
||||
throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(compilationID_index);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitCompilationID(this, data);
|
||||
}
|
||||
|
||||
public final int compilationID_index;
|
||||
}
|
@ -0,0 +1,562 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.5.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ConstantPool {
|
||||
|
||||
public class InvalidIndex extends ConstantPoolException {
|
||||
InvalidIndex(int index) {
|
||||
super(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
// i18n
|
||||
return "invalid index #" + index;
|
||||
}
|
||||
}
|
||||
|
||||
public class UnexpectedEntry extends ConstantPoolException {
|
||||
UnexpectedEntry(int index, int expected_tag, int found_tag) {
|
||||
super(index);
|
||||
this.expected_tag = expected_tag;
|
||||
this.found_tag = found_tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
// i18n?
|
||||
return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
|
||||
}
|
||||
|
||||
public final int expected_tag;
|
||||
public final int found_tag;
|
||||
}
|
||||
|
||||
public class InvalidEntry extends ConstantPoolException {
|
||||
InvalidEntry(int index, int tag) {
|
||||
super(index);
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
// i18n?
|
||||
return "unexpected tag at #" + index + ": " + tag;
|
||||
}
|
||||
|
||||
public final int tag;
|
||||
}
|
||||
|
||||
public class EntryNotFound extends ConstantPoolException {
|
||||
EntryNotFound(Object value) {
|
||||
super(-1);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
// i18n?
|
||||
return "value not found: " + value;
|
||||
}
|
||||
|
||||
public final Object value;
|
||||
}
|
||||
|
||||
public static final int CONSTANT_Utf8 = 1;
|
||||
public static final int CONSTANT_Integer = 3;
|
||||
public static final int CONSTANT_Float = 4;
|
||||
public static final int CONSTANT_Long = 5;
|
||||
public static final int CONSTANT_Double = 6;
|
||||
public static final int CONSTANT_Class = 7;
|
||||
public static final int CONSTANT_String = 8;
|
||||
public static final int CONSTANT_Fieldref = 9;
|
||||
public static final int CONSTANT_Methodref = 10;
|
||||
public static final int CONSTANT_InterfaceMethodref = 11;
|
||||
public static final int CONSTANT_NameAndType = 12;
|
||||
|
||||
ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
|
||||
int count = cr.readUnsignedShort();
|
||||
pool = new CPInfo[count];
|
||||
for (int i = 1; i < count; i++) {
|
||||
int tag = cr.readUnsignedByte();
|
||||
switch (tag) {
|
||||
case CONSTANT_Class:
|
||||
pool[i] = new CONSTANT_Class_info(this, cr);
|
||||
break;
|
||||
|
||||
case CONSTANT_Double:
|
||||
pool[i] = new CONSTANT_Double_info(cr);
|
||||
i++;
|
||||
break;
|
||||
|
||||
case CONSTANT_Fieldref:
|
||||
pool[i] = new CONSTANT_Fieldref_info(this, cr);
|
||||
break;
|
||||
|
||||
case CONSTANT_Float:
|
||||
pool[i] = new CONSTANT_Float_info(cr);
|
||||
break;
|
||||
|
||||
case CONSTANT_Integer:
|
||||
pool[i] = new CONSTANT_Integer_info(cr);
|
||||
break;
|
||||
|
||||
case CONSTANT_InterfaceMethodref:
|
||||
pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
|
||||
break;
|
||||
|
||||
case CONSTANT_Long:
|
||||
pool[i] = new CONSTANT_Long_info(cr);
|
||||
i++;
|
||||
break;
|
||||
|
||||
case CONSTANT_Methodref:
|
||||
pool[i] = new CONSTANT_Methodref_info(this, cr);
|
||||
break;
|
||||
|
||||
case CONSTANT_NameAndType:
|
||||
pool[i] = new CONSTANT_NameAndType_info(this, cr);
|
||||
break;
|
||||
|
||||
case CONSTANT_String:
|
||||
pool[i] = new CONSTANT_String_info(cr);
|
||||
break;
|
||||
|
||||
case CONSTANT_Utf8:
|
||||
pool[i] = new CONSTANT_Utf8_info(cr);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidEntry(i, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ConstantPool(CPInfo[] pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return pool.length;
|
||||
}
|
||||
|
||||
public CPInfo get(int index) throws InvalidIndex {
|
||||
if (index <= 0 || index >= pool.length)
|
||||
throw new InvalidIndex(index);
|
||||
CPInfo info = pool[index];
|
||||
if (info == null) {
|
||||
// this occurs for indices referencing the "second half" of an
|
||||
// 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
|
||||
throw new InvalidIndex(index);
|
||||
}
|
||||
return pool[index];
|
||||
}
|
||||
|
||||
private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
|
||||
CPInfo info = get(index);
|
||||
if (info.getTag() != expected_type)
|
||||
throw new UnexpectedEntry(index, expected_type, info.getTag());
|
||||
return info;
|
||||
}
|
||||
|
||||
public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
|
||||
return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
|
||||
}
|
||||
|
||||
public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
|
||||
return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
|
||||
}
|
||||
|
||||
public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
|
||||
return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
|
||||
}
|
||||
|
||||
public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
|
||||
return getUTF8Info(index).value;
|
||||
}
|
||||
|
||||
public int getUTF8Index(String value) throws EntryNotFound {
|
||||
for (int i = 1; i < pool.length; i++) {
|
||||
CPInfo info = pool[i];
|
||||
if (info instanceof CONSTANT_Utf8_info &&
|
||||
((CONSTANT_Utf8_info) info).value.equals(value))
|
||||
return i;
|
||||
}
|
||||
throw new EntryNotFound(value);
|
||||
}
|
||||
|
||||
private CPInfo[] pool;
|
||||
|
||||
public interface Visitor<R,P> {
|
||||
R visitClass(CONSTANT_Class_info info, P p);
|
||||
R visitDouble(CONSTANT_Double_info info, P p);
|
||||
R visitFieldref(CONSTANT_Fieldref_info info, P p);
|
||||
R visitFloat(CONSTANT_Float_info info, P p);
|
||||
R visitInteger(CONSTANT_Integer_info info, P p);
|
||||
R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
|
||||
R visitLong(CONSTANT_Long_info info, P p);
|
||||
R visitNameAndType(CONSTANT_NameAndType_info info, P p);
|
||||
R visitMethodref(CONSTANT_Methodref_info info, P p);
|
||||
R visitString(CONSTANT_String_info info, P p);
|
||||
R visitUtf8(CONSTANT_Utf8_info info, P p);
|
||||
}
|
||||
|
||||
public static abstract class CPInfo {
|
||||
CPInfo() {
|
||||
this.cp = null;
|
||||
}
|
||||
|
||||
CPInfo(ConstantPool cp) {
|
||||
this.cp = cp;
|
||||
}
|
||||
|
||||
public abstract int getTag();
|
||||
|
||||
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
|
||||
|
||||
protected final ConstantPool cp;
|
||||
}
|
||||
|
||||
public static abstract class CPRefInfo extends CPInfo {
|
||||
protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
|
||||
super(cp);
|
||||
this.tag = tag;
|
||||
class_index = cr.readUnsignedShort();
|
||||
name_and_type_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
|
||||
super(cp);
|
||||
this.tag = tag;
|
||||
this.class_index = class_index;
|
||||
this.name_and_type_index = name_and_type_index;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
|
||||
return cp.getClassInfo(class_index);
|
||||
}
|
||||
|
||||
public String getClassName() throws ConstantPoolException {
|
||||
return cp.getClassInfo(class_index).getName();
|
||||
}
|
||||
|
||||
public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
|
||||
return cp.getNameAndTypeInfo(name_and_type_index);
|
||||
}
|
||||
|
||||
public final int tag;
|
||||
public final int class_index;
|
||||
public final int name_and_type_index;
|
||||
}
|
||||
|
||||
public static class CONSTANT_Class_info extends CPInfo {
|
||||
CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
|
||||
super(cp);
|
||||
name_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public CONSTANT_Class_info(ConstantPool cp, int name_index) {
|
||||
super(cp);
|
||||
this.name_index = name_index;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return CONSTANT_Class;
|
||||
}
|
||||
|
||||
public String getName() throws ConstantPoolException {
|
||||
return cp.getUTF8Value(name_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Class_info[name_index: " + name_index + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitClass(this, data);
|
||||
}
|
||||
|
||||
public final int name_index;
|
||||
}
|
||||
|
||||
public static class CONSTANT_Double_info extends CPInfo {
|
||||
CONSTANT_Double_info(ClassReader cr) throws IOException {
|
||||
value = cr.readDouble();
|
||||
}
|
||||
|
||||
public CONSTANT_Double_info(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return CONSTANT_Double;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Double_info[value: " + value + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitDouble(this, data);
|
||||
}
|
||||
|
||||
public final double value;
|
||||
}
|
||||
|
||||
public static class CONSTANT_Fieldref_info extends CPRefInfo {
|
||||
CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
|
||||
super(cp, cr, CONSTANT_Fieldref);
|
||||
}
|
||||
|
||||
public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
|
||||
super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitFieldref(this, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CONSTANT_Float_info extends CPInfo {
|
||||
CONSTANT_Float_info(ClassReader cr) throws IOException {
|
||||
value = cr.readFloat();
|
||||
}
|
||||
|
||||
public CONSTANT_Float_info(float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return CONSTANT_Float;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Float_info[value: " + value + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitFloat(this, data);
|
||||
}
|
||||
|
||||
public final float value;
|
||||
}
|
||||
|
||||
public static class CONSTANT_Integer_info extends CPInfo {
|
||||
CONSTANT_Integer_info(ClassReader cr) throws IOException {
|
||||
value = cr.readInt();
|
||||
}
|
||||
|
||||
public CONSTANT_Integer_info(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return CONSTANT_Integer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Integer_info[value: " + value + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitInteger(this, data);
|
||||
}
|
||||
|
||||
public final int value;
|
||||
}
|
||||
|
||||
public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
|
||||
CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
|
||||
super(cp, cr, CONSTANT_InterfaceMethodref);
|
||||
}
|
||||
|
||||
public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
|
||||
super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitInterfaceMethodref(this, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CONSTANT_Long_info extends CPInfo {
|
||||
CONSTANT_Long_info(ClassReader cr) throws IOException {
|
||||
value = cr.readLong();
|
||||
}
|
||||
|
||||
public CONSTANT_Long_info(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return CONSTANT_Long;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Long_info[value: " + value + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitLong(this, data);
|
||||
}
|
||||
|
||||
public final long value;
|
||||
}
|
||||
|
||||
public static class CONSTANT_Methodref_info extends CPRefInfo {
|
||||
CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
|
||||
super(cp, cr, CONSTANT_Methodref);
|
||||
}
|
||||
|
||||
public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
|
||||
super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitMethodref(this, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CONSTANT_NameAndType_info extends CPInfo {
|
||||
CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
|
||||
super(cp);
|
||||
name_index = cr.readUnsignedShort();
|
||||
type_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
|
||||
super(cp);
|
||||
this.name_index = name_index;
|
||||
this.type_index = type_index;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return CONSTANT_NameAndType;
|
||||
}
|
||||
|
||||
public String getName() throws ConstantPoolException {
|
||||
return cp.getUTF8Value(name_index);
|
||||
}
|
||||
|
||||
public String getType() throws ConstantPoolException {
|
||||
return cp.getUTF8Value(type_index);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitNameAndType(this, data);
|
||||
}
|
||||
|
||||
public final int name_index;
|
||||
public final int type_index;
|
||||
}
|
||||
|
||||
public static class CONSTANT_String_info extends CPInfo {
|
||||
CONSTANT_String_info(ClassReader cr) throws IOException {
|
||||
string_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public CONSTANT_String_info(ConstantPool cp, int string_index) {
|
||||
super(cp);
|
||||
this.string_index = string_index;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return CONSTANT_String;
|
||||
}
|
||||
|
||||
public String getString() throws ConstantPoolException {
|
||||
return cp.getUTF8Value(string_index);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitString(this, data);
|
||||
}
|
||||
|
||||
public final int string_index;
|
||||
}
|
||||
|
||||
public static class CONSTANT_Utf8_info extends CPInfo {
|
||||
CONSTANT_Utf8_info(ClassReader cr) throws IOException {
|
||||
value = cr.readUTF();
|
||||
}
|
||||
|
||||
public CONSTANT_Utf8_info(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return CONSTANT_Utf8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CONSTANT_Utf8_info[value: " + value + "]";
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitUtf8(this, data);
|
||||
}
|
||||
|
||||
public final String value;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2008 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 com.sun.tools.classfile;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ConstantPoolException extends Exception {
|
||||
ConstantPoolException(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public final int index;
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.2.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ConstantValue_attribute extends Attribute {
|
||||
ConstantValue_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
constantvalue_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public ConstantValue_attribute(ConstantPool constant_pool, int constantvalue_index)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.ConstantValue), constantvalue_index);
|
||||
}
|
||||
|
||||
public ConstantValue_attribute(int name_index, int constantvalue_index) {
|
||||
super(name_index, 2);
|
||||
this.constantvalue_index = constantvalue_index;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitConstantValue(this, data);
|
||||
}
|
||||
|
||||
public final int constantvalue_index;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class DefaultAttribute extends Attribute {
|
||||
DefaultAttribute(ClassReader cr, int name_index, byte[] data) {
|
||||
super(name_index, data.length);
|
||||
info = data;
|
||||
}
|
||||
|
||||
public DefaultAttribute(ConstantPool constant_pool, int name_index, byte[] info) {
|
||||
super(name_index, info.length);
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitDefault(this, p);
|
||||
}
|
||||
|
||||
public final byte[] info;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.15.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Deprecated_attribute extends Attribute {
|
||||
Deprecated_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
}
|
||||
|
||||
public Deprecated_attribute(ConstantPool constant_pool)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.Deprecated));
|
||||
}
|
||||
|
||||
public Deprecated_attribute(int name_index) {
|
||||
super(name_index, 0);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitDeprecated(this, data);
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.4.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Descriptor {
|
||||
public class InvalidDescriptor extends DescriptorException {
|
||||
InvalidDescriptor(String desc) {
|
||||
this.desc = desc;
|
||||
this.index = -1;
|
||||
}
|
||||
|
||||
InvalidDescriptor(String desc, int index) {
|
||||
this.desc = desc;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
// i18n
|
||||
if (index == -1)
|
||||
return "invalid descriptor \"" + desc + "\"";
|
||||
else
|
||||
return "descriptor is invalid at offset " + index + " in \"" + desc + "\"";
|
||||
}
|
||||
|
||||
public final String desc;
|
||||
public final int index;
|
||||
|
||||
}
|
||||
|
||||
public Descriptor(ClassReader cr) throws IOException {
|
||||
this(cr.readUnsignedShort());
|
||||
}
|
||||
|
||||
public Descriptor(int index) {
|
||||
this.index = index;
|
||||
|
||||
}
|
||||
|
||||
public String getValue(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(index);
|
||||
}
|
||||
|
||||
public int getParameterCount(ConstantPool constant_pool)
|
||||
throws ConstantPoolException, InvalidDescriptor {
|
||||
String desc = getValue(constant_pool);
|
||||
int end = desc.indexOf(")");
|
||||
if (end == -1)
|
||||
throw new InvalidDescriptor(desc);
|
||||
parse(desc, 0, end + 1);
|
||||
return count;
|
||||
|
||||
}
|
||||
|
||||
public String getParameterTypes(ConstantPool constant_pool)
|
||||
throws ConstantPoolException, InvalidDescriptor {
|
||||
String desc = getValue(constant_pool);
|
||||
int end = desc.indexOf(")");
|
||||
if (end == -1)
|
||||
throw new InvalidDescriptor(desc);
|
||||
return parse(desc, 0, end + 1);
|
||||
}
|
||||
|
||||
public String getReturnType(ConstantPool constant_pool)
|
||||
throws ConstantPoolException, InvalidDescriptor {
|
||||
String desc = getValue(constant_pool);
|
||||
int end = desc.indexOf(")");
|
||||
if (end == -1)
|
||||
throw new InvalidDescriptor(desc);
|
||||
return parse(desc, end + 1, desc.length());
|
||||
}
|
||||
|
||||
public String getFieldType(ConstantPool constant_pool)
|
||||
throws ConstantPoolException, InvalidDescriptor {
|
||||
String desc = getValue(constant_pool);
|
||||
return parse(desc, 0, desc.length());
|
||||
}
|
||||
|
||||
private String parse(String desc, int start, int end)
|
||||
throws InvalidDescriptor {
|
||||
int p = start;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int dims = 0;
|
||||
count = 0;
|
||||
|
||||
while (p < end) {
|
||||
String type;
|
||||
char ch;
|
||||
switch (ch = desc.charAt(p++)) {
|
||||
case '(':
|
||||
sb.append('(');
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
sb.append(')');
|
||||
continue;
|
||||
|
||||
case '[':
|
||||
dims++;
|
||||
continue;
|
||||
|
||||
case 'B':
|
||||
type = "byte";
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
type = "char";
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
type = "double";
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
type = "float";
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
type = "int";
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
type = "long";
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
int sep = desc.indexOf(';', p);
|
||||
if (sep == -1)
|
||||
throw new InvalidDescriptor(desc, p - 1);
|
||||
type = desc.substring(p, sep).replace('/', '.');
|
||||
p = sep + 1;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
type = "short";
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
type = "boolean";
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
type = "void";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidDescriptor(desc, p - 1);
|
||||
}
|
||||
|
||||
if (sb.length() > 1 && sb.charAt(0) == '(')
|
||||
sb.append(", ");
|
||||
sb.append(type);
|
||||
for ( ; dims > 0; dims-- )
|
||||
sb.append("[]");
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public final int index;
|
||||
private int count;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2008 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 com.sun.tools.classfile;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class DescriptorException extends Exception {
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.7.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class EnclosingMethod_attribute extends Attribute {
|
||||
EnclosingMethod_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
class_index = cr.readUnsignedShort();
|
||||
method_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public EnclosingMethod_attribute(ConstantPool constant_pool, int class_index, int method_index)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.EnclosingMethod), class_index, method_index);
|
||||
}
|
||||
|
||||
public EnclosingMethod_attribute(int name_index, int class_index, int method_index) {
|
||||
super(name_index, 4);
|
||||
this.class_index = class_index;
|
||||
this.method_index = method_index;
|
||||
}
|
||||
|
||||
public String getClassName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getClassInfo(class_index).getName();
|
||||
}
|
||||
|
||||
public String getMethodName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
if (method_index == 0)
|
||||
return "";
|
||||
return constant_pool.getNameAndTypeInfo(method_index).getName();
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitEnclosingMethod(this, data);
|
||||
}
|
||||
|
||||
public final int class_index;
|
||||
public final int method_index;
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.5.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Exceptions_attribute extends Attribute {
|
||||
Exceptions_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
number_of_exceptions = cr.readUnsignedShort();
|
||||
exception_index_table = new int[number_of_exceptions];
|
||||
for (int i = 0; i < number_of_exceptions; i++)
|
||||
exception_index_table[i] = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public Exceptions_attribute(ConstantPool constant_pool, int[] exception_index_table)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.Exceptions), exception_index_table);
|
||||
}
|
||||
|
||||
public Exceptions_attribute(int name_index, int[] exception_index_table) {
|
||||
super(name_index, 2 + 2 * exception_index_table.length);
|
||||
this.number_of_exceptions = exception_index_table.length;
|
||||
this.exception_index_table = exception_index_table;
|
||||
}
|
||||
|
||||
public String getException(int index, ConstantPool constant_pool) throws ConstantPoolException {
|
||||
int exception_index = exception_index_table[index];
|
||||
return constant_pool.getClassInfo(exception_index).getName();
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitExceptions(this, data);
|
||||
}
|
||||
|
||||
public final int number_of_exceptions;
|
||||
public final int[] exception_index_table;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Field {
|
||||
Field(ClassReader cr) throws IOException {
|
||||
access_flags = new AccessFlags(cr);
|
||||
name_index = cr.readUnsignedShort();
|
||||
descriptor = new Descriptor(cr);
|
||||
attributes = new Attributes(cr);
|
||||
}
|
||||
|
||||
public Field(AccessFlags access_flags,
|
||||
int name_index, Descriptor descriptor,
|
||||
Attributes attributes) {
|
||||
this.access_flags = access_flags;
|
||||
this.name_index = name_index;
|
||||
this.descriptor = descriptor;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(name_index);
|
||||
}
|
||||
|
||||
public final AccessFlags access_flags;
|
||||
public final int name_index;
|
||||
public final Descriptor descriptor;
|
||||
public final Attributes attributes;
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.sun.tools.classfile.ConstantPool.*;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.6.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class InnerClasses_attribute extends Attribute {
|
||||
InnerClasses_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
number_of_classes = cr.readUnsignedShort();
|
||||
classes = new Info[number_of_classes];
|
||||
for (int i = 0; i < number_of_classes; i++)
|
||||
classes[i] = new Info(cr);
|
||||
}
|
||||
|
||||
public InnerClasses_attribute(ConstantPool constant_pool, Info[] classes)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.InnerClasses), classes);
|
||||
}
|
||||
|
||||
public InnerClasses_attribute(int name_index, Info[] classes) {
|
||||
super(name_index, 2 + Info.length() * classes.length);
|
||||
this.number_of_classes = classes.length;
|
||||
this.classes = classes;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitInnerClasses(this, data);
|
||||
}
|
||||
|
||||
public final int number_of_classes;
|
||||
public final Info[] classes;
|
||||
|
||||
public static class Info {
|
||||
Info(ClassReader cr) throws IOException {
|
||||
inner_class_info_index = cr.readUnsignedShort();
|
||||
outer_class_info_index = cr.readUnsignedShort();
|
||||
inner_name_index = cr.readUnsignedShort();
|
||||
inner_class_access_flags = new AccessFlags(cr.readUnsignedShort());
|
||||
}
|
||||
|
||||
public CONSTANT_Class_info getInnerClassInfo(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
if (inner_class_info_index == 0)
|
||||
return null;
|
||||
return constant_pool.getClassInfo(inner_class_info_index);
|
||||
}
|
||||
|
||||
public CONSTANT_Class_info getOuterClassInfo(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
if (outer_class_info_index == 0)
|
||||
return null;
|
||||
return constant_pool.getClassInfo(outer_class_info_index);
|
||||
}
|
||||
|
||||
public String getInnerName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
if (inner_name_index == 0)
|
||||
return null;
|
||||
return constant_pool.getUTF8Value(inner_name_index);
|
||||
}
|
||||
|
||||
public static int length() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public final int inner_class_info_index;
|
||||
public final int outer_class_info_index;
|
||||
public final int inner_name_index;
|
||||
public final AccessFlags inner_class_access_flags;
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.12.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class LineNumberTable_attribute extends Attribute {
|
||||
LineNumberTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
line_number_table_length = cr.readUnsignedShort();
|
||||
line_number_table = new Entry[line_number_table_length];
|
||||
for (int i = 0; i < line_number_table_length; i++)
|
||||
line_number_table[i] = new Entry(cr);
|
||||
}
|
||||
|
||||
public LineNumberTable_attribute(ConstantPool constant_pool, Entry[] line_number_table)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.LineNumberTable), line_number_table);
|
||||
}
|
||||
|
||||
public LineNumberTable_attribute(int name_index, Entry[] line_number_table) {
|
||||
super(name_index, line_number_table.length * Entry.length());
|
||||
this.line_number_table_length = line_number_table.length;
|
||||
this.line_number_table = line_number_table;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitLineNumberTable(this, data);
|
||||
}
|
||||
|
||||
public final int line_number_table_length;
|
||||
public final Entry[] line_number_table;
|
||||
|
||||
public static class Entry {
|
||||
Entry(ClassReader cr) throws IOException {
|
||||
start_pc = cr.readUnsignedShort();
|
||||
line_number = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public static int length() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public final int start_pc;
|
||||
public final int line_number;
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.13.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class LocalVariableTable_attribute extends Attribute {
|
||||
LocalVariableTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
local_variable_table_length = cr.readUnsignedShort();
|
||||
local_variable_table = new Entry[local_variable_table_length];
|
||||
for (int i = 0; i < local_variable_table_length; i++)
|
||||
local_variable_table[i] = new Entry(cr);
|
||||
}
|
||||
|
||||
public LocalVariableTable_attribute(ConstantPool constant_pool, Entry[] local_variable_table)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.LocalVariableTable), local_variable_table);
|
||||
}
|
||||
|
||||
public LocalVariableTable_attribute(int name_index, Entry[] local_variable_table) {
|
||||
super(name_index, local_variable_table.length * Entry.length());
|
||||
this.local_variable_table_length = local_variable_table.length;
|
||||
this.local_variable_table = local_variable_table;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitLocalVariableTable(this, data);
|
||||
}
|
||||
|
||||
public final int local_variable_table_length;
|
||||
public final Entry[] local_variable_table;
|
||||
|
||||
public static class Entry {
|
||||
Entry(ClassReader cr) throws IOException {
|
||||
start_pc = cr.readUnsignedShort();
|
||||
length = cr.readUnsignedShort();
|
||||
name_index = cr.readUnsignedShort();
|
||||
descriptor_index = cr.readUnsignedShort();
|
||||
index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public static int length() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public final int start_pc;
|
||||
public final int length;
|
||||
public final int name_index;
|
||||
public final int descriptor_index;
|
||||
public final int index;
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.14.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class LocalVariableTypeTable_attribute extends Attribute {
|
||||
LocalVariableTypeTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
local_variable_table_length = cr.readUnsignedShort();
|
||||
local_variable_table = new Entry[local_variable_table_length];
|
||||
for (int i = 0; i < local_variable_table_length; i++)
|
||||
local_variable_table[i] = new Entry(cr);
|
||||
}
|
||||
|
||||
public LocalVariableTypeTable_attribute(ConstantPool constant_pool, Entry[] local_variable_table)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.LocalVariableTypeTable), local_variable_table);
|
||||
}
|
||||
|
||||
public LocalVariableTypeTable_attribute(int name_index, Entry[] local_variable_table) {
|
||||
super(name_index, local_variable_table.length * Entry.length());
|
||||
this.local_variable_table_length = local_variable_table.length;
|
||||
this.local_variable_table = local_variable_table;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitLocalVariableTypeTable(this, data);
|
||||
}
|
||||
|
||||
public final int local_variable_table_length;
|
||||
public final Entry[] local_variable_table;
|
||||
|
||||
public static class Entry {
|
||||
Entry(ClassReader cr) throws IOException {
|
||||
start_pc = cr.readUnsignedShort();
|
||||
length = cr.readUnsignedShort();
|
||||
name_index = cr.readUnsignedShort();
|
||||
signature_index = cr.readUnsignedShort();
|
||||
index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public static int length() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
public final int start_pc;
|
||||
public final int length;
|
||||
public final int name_index;
|
||||
public final int signature_index;
|
||||
public final int index;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Method {
|
||||
Method(ClassReader cr) throws IOException {
|
||||
access_flags = new AccessFlags(cr);
|
||||
name_index = cr.readUnsignedShort();
|
||||
descriptor = new Descriptor(cr);
|
||||
attributes = new Attributes(cr);
|
||||
}
|
||||
|
||||
public Method(AccessFlags access_flags,
|
||||
int name_index, Descriptor descriptor,
|
||||
Attributes attributes) {
|
||||
this.access_flags = access_flags;
|
||||
this.name_index = name_index;
|
||||
this.descriptor = descriptor;
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public String getName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(name_index);
|
||||
}
|
||||
|
||||
public final AccessFlags access_flags;
|
||||
public final int name_index;
|
||||
public final Descriptor descriptor;
|
||||
public final Attributes attributes;
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 277.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ModuleExportTable_attribute extends Attribute {
|
||||
ModuleExportTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
int export_type_length = cr.readUnsignedShort();
|
||||
export_type_table = new int[export_type_length];
|
||||
for (int i = 0; i < export_type_table.length; i++)
|
||||
export_type_table[i] = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public ModuleExportTable_attribute(ConstantPool cp, int[] export_type_table)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.ModuleExportTable), export_type_table);
|
||||
}
|
||||
|
||||
public ModuleExportTable_attribute(int name_index, int[] export_type_table) {
|
||||
super(name_index, 2 * export_type_table.length);
|
||||
this.export_type_table = export_type_table;
|
||||
}
|
||||
|
||||
public int getExportTypeCount() {
|
||||
return export_type_table.length;
|
||||
}
|
||||
|
||||
public String getExportTypeName(int index, ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(export_type_table[index]);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitModuleExportTable(this, p);
|
||||
}
|
||||
|
||||
public final int[] export_type_table;
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 277.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ModuleMemberTable_attribute extends Attribute {
|
||||
ModuleMemberTable_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
int package_member_length = cr.readUnsignedShort();
|
||||
package_member_table = new int[package_member_length];
|
||||
for (int i = 0; i < package_member_table.length; i++)
|
||||
package_member_table[i] = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public ModuleMemberTable_attribute(ConstantPool cp, int[] package_member_table)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.ModuleMemberTable), package_member_table);
|
||||
}
|
||||
|
||||
public ModuleMemberTable_attribute(int name_index, int[] package_member_table) {
|
||||
super(name_index, 2 * package_member_table.length);
|
||||
this.package_member_table = package_member_table;
|
||||
}
|
||||
|
||||
public int getPackageMemberCount() {
|
||||
return package_member_table.length;
|
||||
}
|
||||
|
||||
public String getPackageMemberName(int index, ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(package_member_table[index]);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitModuleMemberTable(this, p);
|
||||
}
|
||||
|
||||
public final int[] package_member_table;
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JSR 277.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Module_attribute extends Attribute {
|
||||
Module_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
module_name = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public Module_attribute(ConstantPool constant_pool, int module_name)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.Module), module_name);
|
||||
}
|
||||
|
||||
public Module_attribute(int name_index, int module_name) {
|
||||
super(name_index, 2);
|
||||
this.module_name = module_name;
|
||||
}
|
||||
|
||||
public String getModuleName(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(module_name);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitModule(this, data);
|
||||
}
|
||||
|
||||
public final int module_name;
|
||||
|
||||
}
|
868
langtools/src/share/classes/com/sun/tools/classfile/OpCodes.java
Normal file
868
langtools/src/share/classes/com/sun/tools/classfile/OpCodes.java
Normal file
@ -0,0 +1,868 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 6.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class OpCodes {
|
||||
|
||||
public static int opcLength(int opc) throws IllegalArgumentException {
|
||||
switch (opc >> 8) {
|
||||
case 0:
|
||||
return opcLengthsTab[opc];
|
||||
case opc_wide:
|
||||
switch (opc & 0xFF) {
|
||||
case opc_aload:
|
||||
case opc_astore:
|
||||
case opc_fload:
|
||||
case opc_fstore:
|
||||
case opc_iload:
|
||||
case opc_istore:
|
||||
case opc_lload:
|
||||
case opc_lstore:
|
||||
case opc_dload:
|
||||
case opc_dstore:
|
||||
case opc_ret:
|
||||
return 4;
|
||||
case opc_iinc:
|
||||
return 6;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
case opc_nonpriv:
|
||||
case opc_priv:
|
||||
return 2;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public static String opcName(int opc) {
|
||||
try {
|
||||
switch (opc >> 8) {
|
||||
case 0:
|
||||
return opcNamesTab[opc];
|
||||
case opc_wide:
|
||||
{
|
||||
String mnem = opcNamesTab[opc & 0xFF] + "_w";
|
||||
if (mnemocodes.get(mnem) == null) {
|
||||
return null; // non-existent opcode
|
||||
}
|
||||
return mnem;
|
||||
}
|
||||
case opc_nonpriv:
|
||||
return opcExtNamesTab[opc & 0xFF];
|
||||
case opc_priv:
|
||||
return opcPrivExtNamesTab[opc & 0xFF];
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
switch (opc) {
|
||||
case opc_nonpriv:
|
||||
return "nonpriv";
|
||||
case opc_priv:
|
||||
return "priv";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Opcodes */
|
||||
public static final int opc_dead = -2;
|
||||
public static final int opc_label = -1;
|
||||
public static final int opc_nop = 0;
|
||||
public static final int opc_aconst_null = 1;
|
||||
public static final int opc_iconst_m1 = 2;
|
||||
public static final int opc_iconst_0 = 3;
|
||||
public static final int opc_iconst_1 = 4;
|
||||
public static final int opc_iconst_2 = 5;
|
||||
public static final int opc_iconst_3 = 6;
|
||||
public static final int opc_iconst_4 = 7;
|
||||
public static final int opc_iconst_5 = 8;
|
||||
public static final int opc_lconst_0 = 9;
|
||||
public static final int opc_lconst_1 = 10;
|
||||
public static final int opc_fconst_0 = 11;
|
||||
public static final int opc_fconst_1 = 12;
|
||||
public static final int opc_fconst_2 = 13;
|
||||
public static final int opc_dconst_0 = 14;
|
||||
public static final int opc_dconst_1 = 15;
|
||||
public static final int opc_bipush = 16;
|
||||
public static final int opc_sipush = 17;
|
||||
public static final int opc_ldc = 18;
|
||||
public static final int opc_ldc_w = 19;
|
||||
public static final int opc_ldc2_w = 20;
|
||||
public static final int opc_iload = 21;
|
||||
public static final int opc_lload = 22;
|
||||
public static final int opc_fload = 23;
|
||||
public static final int opc_dload = 24;
|
||||
public static final int opc_aload = 25;
|
||||
public static final int opc_iload_0 = 26;
|
||||
public static final int opc_iload_1 = 27;
|
||||
public static final int opc_iload_2 = 28;
|
||||
public static final int opc_iload_3 = 29;
|
||||
public static final int opc_lload_0 = 30;
|
||||
public static final int opc_lload_1 = 31;
|
||||
public static final int opc_lload_2 = 32;
|
||||
public static final int opc_lload_3 = 33;
|
||||
public static final int opc_fload_0 = 34;
|
||||
public static final int opc_fload_1 = 35;
|
||||
public static final int opc_fload_2 = 36;
|
||||
public static final int opc_fload_3 = 37;
|
||||
public static final int opc_dload_0 = 38;
|
||||
public static final int opc_dload_1 = 39;
|
||||
public static final int opc_dload_2 = 40;
|
||||
public static final int opc_dload_3 = 41;
|
||||
public static final int opc_aload_0 = 42;
|
||||
public static final int opc_aload_1 = 43;
|
||||
public static final int opc_aload_2 = 44;
|
||||
public static final int opc_aload_3 = 45;
|
||||
public static final int opc_iaload = 46;
|
||||
public static final int opc_laload = 47;
|
||||
public static final int opc_faload = 48;
|
||||
public static final int opc_daload = 49;
|
||||
public static final int opc_aaload = 50;
|
||||
public static final int opc_baload = 51;
|
||||
public static final int opc_caload = 52;
|
||||
public static final int opc_saload = 53;
|
||||
public static final int opc_istore = 54;
|
||||
public static final int opc_lstore = 55;
|
||||
public static final int opc_fstore = 56;
|
||||
public static final int opc_dstore = 57;
|
||||
public static final int opc_astore = 58;
|
||||
public static final int opc_istore_0 = 59;
|
||||
public static final int opc_istore_1 = 60;
|
||||
public static final int opc_istore_2 = 61;
|
||||
public static final int opc_istore_3 = 62;
|
||||
public static final int opc_lstore_0 = 63;
|
||||
public static final int opc_lstore_1 = 64;
|
||||
public static final int opc_lstore_2 = 65;
|
||||
public static final int opc_lstore_3 = 66;
|
||||
public static final int opc_fstore_0 = 67;
|
||||
public static final int opc_fstore_1 = 68;
|
||||
public static final int opc_fstore_2 = 69;
|
||||
public static final int opc_fstore_3 = 70;
|
||||
public static final int opc_dstore_0 = 71;
|
||||
public static final int opc_dstore_1 = 72;
|
||||
public static final int opc_dstore_2 = 73;
|
||||
public static final int opc_dstore_3 = 74;
|
||||
public static final int opc_astore_0 = 75;
|
||||
public static final int opc_astore_1 = 76;
|
||||
public static final int opc_astore_2 = 77;
|
||||
public static final int opc_astore_3 = 78;
|
||||
public static final int opc_iastore = 79;
|
||||
public static final int opc_lastore = 80;
|
||||
public static final int opc_fastore = 81;
|
||||
public static final int opc_dastore = 82;
|
||||
public static final int opc_aastore = 83;
|
||||
public static final int opc_bastore = 84;
|
||||
public static final int opc_castore = 85;
|
||||
public static final int opc_sastore = 86;
|
||||
public static final int opc_pop = 87;
|
||||
public static final int opc_pop2 = 88;
|
||||
public static final int opc_dup = 89;
|
||||
public static final int opc_dup_x1 = 90;
|
||||
public static final int opc_dup_x2 = 91;
|
||||
public static final int opc_dup2 = 92;
|
||||
public static final int opc_dup2_x1 = 93;
|
||||
public static final int opc_dup2_x2 = 94;
|
||||
public static final int opc_swap = 95;
|
||||
public static final int opc_iadd = 96;
|
||||
public static final int opc_ladd = 97;
|
||||
public static final int opc_fadd = 98;
|
||||
public static final int opc_dadd = 99;
|
||||
public static final int opc_isub = 100;
|
||||
public static final int opc_lsub = 101;
|
||||
public static final int opc_fsub = 102;
|
||||
public static final int opc_dsub = 103;
|
||||
public static final int opc_imul = 104;
|
||||
public static final int opc_lmul = 105;
|
||||
public static final int opc_fmul = 106;
|
||||
public static final int opc_dmul = 107;
|
||||
public static final int opc_idiv = 108;
|
||||
public static final int opc_ldiv = 109;
|
||||
public static final int opc_fdiv = 110;
|
||||
public static final int opc_ddiv = 111;
|
||||
public static final int opc_irem = 112;
|
||||
public static final int opc_lrem = 113;
|
||||
public static final int opc_frem = 114;
|
||||
public static final int opc_drem = 115;
|
||||
public static final int opc_ineg = 116;
|
||||
public static final int opc_lneg = 117;
|
||||
public static final int opc_fneg = 118;
|
||||
public static final int opc_dneg = 119;
|
||||
public static final int opc_ishl = 120;
|
||||
public static final int opc_lshl = 121;
|
||||
public static final int opc_ishr = 122;
|
||||
public static final int opc_lshr = 123;
|
||||
public static final int opc_iushr = 124;
|
||||
public static final int opc_lushr = 125;
|
||||
public static final int opc_iand = 126;
|
||||
public static final int opc_land = 127;
|
||||
public static final int opc_ior = 128;
|
||||
public static final int opc_lor = 129;
|
||||
public static final int opc_ixor = 130;
|
||||
public static final int opc_lxor = 131;
|
||||
public static final int opc_iinc = 132;
|
||||
public static final int opc_i2l = 133;
|
||||
public static final int opc_i2f = 134;
|
||||
public static final int opc_i2d = 135;
|
||||
public static final int opc_l2i = 136;
|
||||
public static final int opc_l2f = 137;
|
||||
public static final int opc_l2d = 138;
|
||||
public static final int opc_f2i = 139;
|
||||
public static final int opc_f2l = 140;
|
||||
public static final int opc_f2d = 141;
|
||||
public static final int opc_d2i = 142;
|
||||
public static final int opc_d2l = 143;
|
||||
public static final int opc_d2f = 144;
|
||||
public static final int opc_i2b = 145;
|
||||
public static final int opc_int2byte = 145;
|
||||
public static final int opc_i2c = 146;
|
||||
public static final int opc_int2char = 146;
|
||||
public static final int opc_i2s = 147;
|
||||
public static final int opc_int2short = 147;
|
||||
public static final int opc_lcmp = 148;
|
||||
public static final int opc_fcmpl = 149;
|
||||
public static final int opc_fcmpg = 150;
|
||||
public static final int opc_dcmpl = 151;
|
||||
public static final int opc_dcmpg = 152;
|
||||
public static final int opc_ifeq = 153;
|
||||
public static final int opc_ifne = 154;
|
||||
public static final int opc_iflt = 155;
|
||||
public static final int opc_ifge = 156;
|
||||
public static final int opc_ifgt = 157;
|
||||
public static final int opc_ifle = 158;
|
||||
public static final int opc_if_icmpeq = 159;
|
||||
public static final int opc_if_icmpne = 160;
|
||||
public static final int opc_if_icmplt = 161;
|
||||
public static final int opc_if_icmpge = 162;
|
||||
public static final int opc_if_icmpgt = 163;
|
||||
public static final int opc_if_icmple = 164;
|
||||
public static final int opc_if_acmpeq = 165;
|
||||
public static final int opc_if_acmpne = 166;
|
||||
public static final int opc_goto = 167;
|
||||
public static final int opc_jsr = 168;
|
||||
public static final int opc_ret = 169;
|
||||
public static final int opc_tableswitch = 170;
|
||||
public static final int opc_lookupswitch = 171;
|
||||
public static final int opc_ireturn = 172;
|
||||
public static final int opc_lreturn = 173;
|
||||
public static final int opc_freturn = 174;
|
||||
public static final int opc_dreturn = 175;
|
||||
public static final int opc_areturn = 176;
|
||||
public static final int opc_return = 177;
|
||||
public static final int opc_getstatic = 178;
|
||||
public static final int opc_putstatic = 179;
|
||||
public static final int opc_getfield = 180;
|
||||
public static final int opc_putfield = 181;
|
||||
public static final int opc_invokevirtual = 182;
|
||||
public static final int opc_invokenonvirtual = 183;
|
||||
public static final int opc_invokespecial = 183;
|
||||
public static final int opc_invokestatic = 184;
|
||||
public static final int opc_invokeinterface = 185;
|
||||
// public static final int opc_xxxunusedxxx = 186;
|
||||
public static final int opc_new = 187;
|
||||
public static final int opc_newarray = 188;
|
||||
public static final int opc_anewarray = 189;
|
||||
public static final int opc_arraylength = 190;
|
||||
public static final int opc_athrow = 191;
|
||||
public static final int opc_checkcast = 192;
|
||||
public static final int opc_instanceof = 193;
|
||||
public static final int opc_monitorenter = 194;
|
||||
public static final int opc_monitorexit = 195;
|
||||
public static final int opc_wide = 196;
|
||||
public static final int opc_multianewarray = 197;
|
||||
public static final int opc_ifnull = 198;
|
||||
public static final int opc_ifnonnull = 199;
|
||||
public static final int opc_goto_w = 200;
|
||||
public static final int opc_jsr_w = 201;
|
||||
|
||||
/* Pseudo-instructions */
|
||||
public static final int opc_bytecode = 203;
|
||||
public static final int opc_try = 204;
|
||||
public static final int opc_endtry = 205;
|
||||
public static final int opc_catch = 206;
|
||||
public static final int opc_var = 207;
|
||||
public static final int opc_endvar = 208;
|
||||
public static final int opc_localsmap = 209;
|
||||
public static final int opc_stackmap = 210;
|
||||
|
||||
/* PicoJava prefixes */
|
||||
public static final int opc_nonpriv = 254;
|
||||
public static final int opc_priv = 255;
|
||||
|
||||
/* Wide instructions */
|
||||
public static final int opc_iload_w = (opc_wide << 8 ) | opc_iload;
|
||||
public static final int opc_lload_w = (opc_wide << 8 ) | opc_lload;
|
||||
public static final int opc_fload_w = (opc_wide << 8 ) | opc_fload;
|
||||
public static final int opc_dload_w = (opc_wide << 8 ) | opc_dload;
|
||||
public static final int opc_aload_w = (opc_wide << 8 ) | opc_aload;
|
||||
public static final int opc_istore_w = (opc_wide << 8 ) | opc_istore;
|
||||
public static final int opc_lstore_w = (opc_wide << 8 ) | opc_lstore;
|
||||
public static final int opc_fstore_w = (opc_wide << 8 ) | opc_fstore;
|
||||
public static final int opc_dstore_w = (opc_wide << 8 ) | opc_dstore;
|
||||
public static final int opc_astore_w = (opc_wide << 8 ) | opc_astore;
|
||||
public static final int opc_ret_w = (opc_wide << 8 ) | opc_ret;
|
||||
public static final int opc_iinc_w = (opc_wide << 8 ) | opc_iinc;
|
||||
|
||||
/* Opcode Names */
|
||||
private static final String opcNamesTab[] = {
|
||||
"nop",
|
||||
"aconst_null",
|
||||
"iconst_m1",
|
||||
"iconst_0",
|
||||
"iconst_1",
|
||||
"iconst_2",
|
||||
"iconst_3",
|
||||
"iconst_4",
|
||||
"iconst_5",
|
||||
"lconst_0",
|
||||
"lconst_1",
|
||||
"fconst_0",
|
||||
"fconst_1",
|
||||
"fconst_2",
|
||||
"dconst_0",
|
||||
"dconst_1",
|
||||
"bipush",
|
||||
"sipush",
|
||||
"ldc",
|
||||
"ldc_w",
|
||||
"ldc2_w",
|
||||
"iload",
|
||||
"lload",
|
||||
"fload",
|
||||
"dload",
|
||||
"aload",
|
||||
"iload_0",
|
||||
"iload_1",
|
||||
"iload_2",
|
||||
"iload_3",
|
||||
"lload_0",
|
||||
"lload_1",
|
||||
"lload_2",
|
||||
"lload_3",
|
||||
"fload_0",
|
||||
"fload_1",
|
||||
"fload_2",
|
||||
"fload_3",
|
||||
"dload_0",
|
||||
"dload_1",
|
||||
"dload_2",
|
||||
"dload_3",
|
||||
"aload_0",
|
||||
"aload_1",
|
||||
"aload_2",
|
||||
"aload_3",
|
||||
"iaload",
|
||||
"laload",
|
||||
"faload",
|
||||
"daload",
|
||||
"aaload",
|
||||
"baload",
|
||||
"caload",
|
||||
"saload",
|
||||
"istore",
|
||||
"lstore",
|
||||
"fstore",
|
||||
"dstore",
|
||||
"astore",
|
||||
"istore_0",
|
||||
"istore_1",
|
||||
"istore_2",
|
||||
"istore_3",
|
||||
"lstore_0",
|
||||
"lstore_1",
|
||||
"lstore_2",
|
||||
"lstore_3",
|
||||
"fstore_0",
|
||||
"fstore_1",
|
||||
"fstore_2",
|
||||
"fstore_3",
|
||||
"dstore_0",
|
||||
"dstore_1",
|
||||
"dstore_2",
|
||||
"dstore_3",
|
||||
"astore_0",
|
||||
"astore_1",
|
||||
"astore_2",
|
||||
"astore_3",
|
||||
"iastore",
|
||||
"lastore",
|
||||
"fastore",
|
||||
"dastore",
|
||||
"aastore",
|
||||
"bastore",
|
||||
"castore",
|
||||
"sastore",
|
||||
"pop",
|
||||
"pop2",
|
||||
"dup",
|
||||
"dup_x1",
|
||||
"dup_x2",
|
||||
"dup2",
|
||||
"dup2_x1",
|
||||
"dup2_x2",
|
||||
"swap",
|
||||
"iadd",
|
||||
"ladd",
|
||||
"fadd",
|
||||
"dadd",
|
||||
"isub",
|
||||
"lsub",
|
||||
"fsub",
|
||||
"dsub",
|
||||
"imul",
|
||||
"lmul",
|
||||
"fmul",
|
||||
"dmul",
|
||||
"idiv",
|
||||
"ldiv",
|
||||
"fdiv",
|
||||
"ddiv",
|
||||
"irem",
|
||||
"lrem",
|
||||
"frem",
|
||||
"drem",
|
||||
"ineg",
|
||||
"lneg",
|
||||
"fneg",
|
||||
"dneg",
|
||||
"ishl",
|
||||
"lshl",
|
||||
"ishr",
|
||||
"lshr",
|
||||
"iushr",
|
||||
"lushr",
|
||||
"iand",
|
||||
"land",
|
||||
"ior",
|
||||
"lor",
|
||||
"ixor",
|
||||
"lxor",
|
||||
"iinc",
|
||||
"i2l",
|
||||
"i2f",
|
||||
"i2d",
|
||||
"l2i",
|
||||
"l2f",
|
||||
"l2d",
|
||||
"f2i",
|
||||
"f2l",
|
||||
"f2d",
|
||||
"d2i",
|
||||
"d2l",
|
||||
"d2f",
|
||||
"i2b",
|
||||
"i2c",
|
||||
"i2s",
|
||||
"lcmp",
|
||||
"fcmpl",
|
||||
"fcmpg",
|
||||
"dcmpl",
|
||||
"dcmpg",
|
||||
"ifeq",
|
||||
"ifne",
|
||||
"iflt",
|
||||
"ifge",
|
||||
"ifgt",
|
||||
"ifle",
|
||||
"if_icmpeq",
|
||||
"if_icmpne",
|
||||
"if_icmplt",
|
||||
"if_icmpge",
|
||||
"if_icmpgt",
|
||||
"if_icmple",
|
||||
"if_acmpeq",
|
||||
"if_acmpne",
|
||||
"goto",
|
||||
"jsr",
|
||||
"ret",
|
||||
"tableswitch",
|
||||
"lookupswitch",
|
||||
"ireturn",
|
||||
"lreturn",
|
||||
"freturn",
|
||||
"dreturn",
|
||||
"areturn",
|
||||
"return",
|
||||
"getstatic",
|
||||
"putstatic",
|
||||
"getfield",
|
||||
"putfield",
|
||||
"invokevirtual",
|
||||
"invokespecial", // was "invokenonvirtual",
|
||||
"invokestatic",
|
||||
"invokeinterface",
|
||||
"bytecode 186", //"xxxunusedxxx",
|
||||
"new",
|
||||
"newarray",
|
||||
"anewarray",
|
||||
"arraylength",
|
||||
"athrow",
|
||||
"checkcast",
|
||||
"instanceof",
|
||||
"monitorenter",
|
||||
"monitorexit",
|
||||
null, // "wide",
|
||||
"multianewarray",
|
||||
"ifnull",
|
||||
"ifnonnull",
|
||||
"goto_w",
|
||||
"jsr_w",
|
||||
"bytecode 202", // "breakpoint",
|
||||
"bytecode",
|
||||
"try",
|
||||
"endtry",
|
||||
"catch",
|
||||
"var",
|
||||
"endvar",
|
||||
"locals_map",
|
||||
"stack_map"
|
||||
};
|
||||
|
||||
/* Opcode Lengths */
|
||||
private static final int opcLengthsTab[] = {
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
2,
|
||||
3,
|
||||
3,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
2,
|
||||
99,
|
||||
99,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
5,
|
||||
0,
|
||||
3,
|
||||
2,
|
||||
3,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
1,
|
||||
1,
|
||||
0, // wide
|
||||
4,
|
||||
3,
|
||||
3,
|
||||
5,
|
||||
5,
|
||||
1,
|
||||
1, 0, 0, 0, 0, 0 // pseudo
|
||||
};
|
||||
|
||||
/* Type codes, used in newarray opcode */
|
||||
public static final int T_CLASS = 0x00000002;
|
||||
public static final int T_BOOLEAN = 0x00000004;
|
||||
public static final int T_CHAR = 0x00000005;
|
||||
public static final int T_FLOAT = 0x00000006;
|
||||
public static final int T_DOUBLE = 0x00000007;
|
||||
public static final int T_BYTE = 0x00000008;
|
||||
public static final int T_SHORT = 0x00000009;
|
||||
public static final int T_INT = 0x0000000a;
|
||||
public static final int T_LONG = 0x0000000b;
|
||||
|
||||
private static HashMap<String,Integer> mnemocodes = new HashMap<String,Integer>(301, 0.5f);
|
||||
private static String opcExtNamesTab[]=new String[128];
|
||||
private static String opcPrivExtNamesTab[]=new String[128];
|
||||
|
||||
private static void defineNonPriv(int opc, String mnem) {
|
||||
mnemocodes.put(opcExtNamesTab[opc] = mnem, opc_nonpriv * 256 + opc);
|
||||
}
|
||||
|
||||
private static void definePriv(int opc, String mnem) {
|
||||
mnemocodes.put(opcPrivExtNamesTab[opc] = "priv_" + mnem, opc_priv * 256 + opc);
|
||||
}
|
||||
|
||||
private static void defineExt(int opc, String mnem) {
|
||||
defineNonPriv(opc, mnem);
|
||||
definePriv(opc, mnem);
|
||||
}
|
||||
|
||||
static {
|
||||
for (int i = 0; i < opc_wide; i++) {
|
||||
mnemocodes.put(opcNamesTab[i], i);
|
||||
}
|
||||
for (int i = opc_wide + 1; i < opcNamesTab.length; i++) {
|
||||
mnemocodes.put(opcNamesTab[i], i);
|
||||
}
|
||||
mnemocodes.put("invokenonvirtual", opc_invokespecial);
|
||||
|
||||
mnemocodes.put("iload_w", opc_iload_w);
|
||||
mnemocodes.put("lload_w", opc_lload_w);
|
||||
mnemocodes.put("fload_w", opc_fload_w);
|
||||
mnemocodes.put("dload_w", opc_dload_w);
|
||||
mnemocodes.put("aload_w", opc_aload_w);
|
||||
mnemocodes.put("istore_w", opc_istore_w);
|
||||
mnemocodes.put("lstore_w", opc_lstore_w);
|
||||
mnemocodes.put("fstore_w", opc_fstore_w);
|
||||
mnemocodes.put("dstore_w", opc_dstore_w);
|
||||
mnemocodes.put("astore_w", opc_astore_w);
|
||||
mnemocodes.put("ret_w", opc_ret_w);
|
||||
mnemocodes.put("iinc_w", opc_iinc_w);
|
||||
|
||||
mnemocodes.put("nonpriv", opc_nonpriv);
|
||||
mnemocodes.put("priv", opc_priv);
|
||||
|
||||
defineExt(0, "load_ubyte");
|
||||
defineExt(1, "load_byte");
|
||||
defineExt(2, "load_char");
|
||||
defineExt(3, "load_short");
|
||||
defineExt(4, "load_word");
|
||||
defineExt(10, "load_char_oe");
|
||||
defineExt(11, "load_short_oe");
|
||||
defineExt(12, "load_word_oe");
|
||||
defineExt(16, "ncload_ubyte");
|
||||
defineExt(17, "ncload_byte");
|
||||
defineExt(18, "ncload_char");
|
||||
defineExt(19, "ncload_short");
|
||||
defineExt(20, "ncload_word");
|
||||
defineExt(26, "ncload_char_oe");
|
||||
defineExt(27, "ncload_short_oe");
|
||||
defineExt(28, "ncload_word_oe");
|
||||
defineExt(30, "cache_flush");
|
||||
defineExt(32, "store_byte");
|
||||
defineExt(34, "store_short");
|
||||
defineExt(36, "store_word");
|
||||
defineExt(42, "store_short_oe");
|
||||
defineExt(44, "store_word_oe");
|
||||
defineExt(48, "ncstore_byte");
|
||||
defineExt(50, "ncstore_short");
|
||||
defineExt(52, "ncstore_word");
|
||||
defineExt(58, "ncstore_short_oe");
|
||||
defineExt(60, "ncstore_word_oe");
|
||||
defineExt(62, "zero_line");
|
||||
defineNonPriv(5, "ret_from_sub");
|
||||
defineNonPriv(63, "enter_sync_method");
|
||||
definePriv(5, "ret_from_trap");
|
||||
definePriv(6, "read_dcache_tag");
|
||||
definePriv(7, "read_dcache_data");
|
||||
definePriv(14, "read_icache_tag");
|
||||
definePriv(15, "read_icache_data");
|
||||
definePriv(22, "powerdown");
|
||||
definePriv(23, "read_scache_data");
|
||||
definePriv(31, "cache_index_flush");
|
||||
definePriv(38, "write_dcache_tag");
|
||||
definePriv(39, "write_dcache_data");
|
||||
definePriv(46, "write_icache_tag");
|
||||
definePriv(47, "write_icache_data");
|
||||
definePriv(54, "reset");
|
||||
definePriv(55, "write_scache_data");
|
||||
for (int i = 0; i < 32; i++) {
|
||||
definePriv(i + 64, "read_reg_" + i);
|
||||
}
|
||||
for (int i = 0; i < 32; i++) {
|
||||
definePriv(i + 96, "write_reg_" + i);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.16 and 4.8.17.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public abstract class RuntimeAnnotations_attribute extends Attribute {
|
||||
protected RuntimeAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(name_index, length);
|
||||
int num_annotations = cr.readUnsignedShort();
|
||||
annotations = new Annotation[num_annotations];
|
||||
for (int i = 0; i < annotations.length; i++)
|
||||
annotations[i] = new Annotation(cr);
|
||||
}
|
||||
|
||||
protected RuntimeAnnotations_attribute(int name_index, Annotation[] annotations) {
|
||||
super(name_index, length(annotations));
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
private static int length(Annotation[] annos) {
|
||||
int n = 2;
|
||||
for (Annotation anno: annos)
|
||||
n += anno.length();
|
||||
return n;
|
||||
}
|
||||
|
||||
public final Annotation[] annotations;
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.17.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class RuntimeInvisibleAnnotations_attribute extends RuntimeAnnotations_attribute {
|
||||
RuntimeInvisibleAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, AttributeException {
|
||||
super(cr, name_index, length);
|
||||
}
|
||||
|
||||
public RuntimeInvisibleAnnotations_attribute(ConstantPool cp, Annotation[] annotations)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.RuntimeInvisibleAnnotations), annotations);
|
||||
}
|
||||
|
||||
public RuntimeInvisibleAnnotations_attribute(int name_index, Annotation[] annotations) {
|
||||
super(name_index, annotations);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitRuntimeInvisibleAnnotations(this, p);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.18.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class RuntimeInvisibleParameterAnnotations_attribute extends RuntimeParameterAnnotations_attribute {
|
||||
RuntimeInvisibleParameterAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(cr, name_index, length);
|
||||
}
|
||||
|
||||
public RuntimeInvisibleParameterAnnotations_attribute(ConstantPool cp, Annotation[][] parameter_annotations)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.RuntimeInvisibleParameterAnnotations), parameter_annotations);
|
||||
}
|
||||
|
||||
public RuntimeInvisibleParameterAnnotations_attribute(int name_index, Annotation[][] parameter_annotations) {
|
||||
super(name_index, parameter_annotations);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitRuntimeInvisibleParameterAnnotations(this, p);
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.18 and 4.8.19.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public abstract class RuntimeParameterAnnotations_attribute extends Attribute {
|
||||
RuntimeParameterAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(name_index, length);
|
||||
int num_parameters = cr.readUnsignedByte();
|
||||
parameter_annotations = new Annotation[num_parameters][];
|
||||
for (int p = 0; p < parameter_annotations.length; p++) {
|
||||
int num_annotations = cr.readUnsignedShort();
|
||||
Annotation[] annotations = new Annotation[num_annotations];
|
||||
for (int i = 0; i < num_annotations; i++)
|
||||
annotations[i] = new Annotation(cr);
|
||||
parameter_annotations[p] = annotations;
|
||||
}
|
||||
}
|
||||
|
||||
protected RuntimeParameterAnnotations_attribute(int name_index, Annotation[][] parameter_annotations) {
|
||||
super(name_index, length(parameter_annotations));
|
||||
this.parameter_annotations = parameter_annotations;
|
||||
}
|
||||
|
||||
private static int length(Annotation[][] anno_arrays) {
|
||||
int n = 1;
|
||||
for (Annotation[] anno_array: anno_arrays) {
|
||||
n += 2;
|
||||
for (Annotation anno: anno_array)
|
||||
n += anno.length();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public final Annotation[][] parameter_annotations;
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.16.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class RuntimeVisibleAnnotations_attribute extends RuntimeAnnotations_attribute {
|
||||
RuntimeVisibleAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(cr, name_index, length);
|
||||
}
|
||||
|
||||
public RuntimeVisibleAnnotations_attribute(ConstantPool cp, Annotation[] annotations)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.RuntimeVisibleAnnotations), annotations);
|
||||
}
|
||||
|
||||
public RuntimeVisibleAnnotations_attribute(int name_index, Annotation[] annotations) {
|
||||
super(name_index, annotations);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitRuntimeVisibleAnnotations(this, p);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.18.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class RuntimeVisibleParameterAnnotations_attribute extends RuntimeParameterAnnotations_attribute {
|
||||
RuntimeVisibleParameterAnnotations_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, Annotation.InvalidAnnotation {
|
||||
super(cr, name_index, length);
|
||||
}
|
||||
|
||||
public RuntimeVisibleParameterAnnotations_attribute(ConstantPool cp, Annotation[][] parameter_annotations)
|
||||
throws ConstantPoolException {
|
||||
this(cp.getUTF8Index(Attribute.RuntimeVisibleParameterAnnotations), parameter_annotations);
|
||||
}
|
||||
|
||||
public RuntimeVisibleParameterAnnotations_attribute(int name_index, Annotation[][] parameter_annotations) {
|
||||
super(name_index, parameter_annotations);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitRuntimeVisibleParameterAnnotations(this, p);
|
||||
}
|
||||
}
|
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* See JVMS3 4.4.4.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Signature extends Descriptor {
|
||||
|
||||
public Signature(int index) {
|
||||
super(index);
|
||||
}
|
||||
|
||||
public Type getType(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
if (type == null)
|
||||
type = parse(getValue(constant_pool));
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParameterCount(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
Type.MethodType m = (Type.MethodType) getType(constant_pool);
|
||||
return m.argTypes.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameterTypes(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
Type.MethodType m = (Type.MethodType) getType(constant_pool);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
String sep = "";
|
||||
for (Type argType: m.argTypes) {
|
||||
sb.append(sep);
|
||||
sb.append(argType);
|
||||
sep = ", ";
|
||||
}
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReturnType(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
Type.MethodType m = (Type.MethodType) getType(constant_pool);
|
||||
return m.returnType.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFieldType(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return getType(constant_pool).toString();
|
||||
}
|
||||
|
||||
private Type parse(String sig) {
|
||||
this.sig = sig;
|
||||
sigp = 0;
|
||||
|
||||
List<Type> typeArgTypes = null;
|
||||
if (sig.charAt(sigp) == '<')
|
||||
typeArgTypes = parseTypeArgTypes();
|
||||
|
||||
if (sig.charAt(sigp) == '(') {
|
||||
List<Type> argTypes = parseTypeSignatures(')');
|
||||
Type returnType = parseTypeSignature();
|
||||
List<Type> throwsTypes = null;
|
||||
while (sigp < sig.length() && sig.charAt(sigp) == '^') {
|
||||
sigp++;
|
||||
if (throwsTypes == null)
|
||||
throwsTypes = new ArrayList<Type>();
|
||||
throwsTypes.add(parseTypeSignature());
|
||||
}
|
||||
return new Type.MethodType(typeArgTypes, argTypes, returnType, throwsTypes);
|
||||
} else {
|
||||
Type t = parseTypeSignature();
|
||||
if (typeArgTypes == null && sigp == sig.length())
|
||||
return t;
|
||||
Type superclass = t;
|
||||
List<Type> superinterfaces = new ArrayList<Type>();
|
||||
while (sigp < sig.length())
|
||||
superinterfaces.add(parseTypeSignature());
|
||||
return new Type.ClassSigType(typeArgTypes, superclass, superinterfaces);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Type parseTypeSignature() {
|
||||
switch (sig.charAt(sigp)) {
|
||||
case 'B':
|
||||
sigp++;
|
||||
return new Type.SimpleType("byte");
|
||||
|
||||
case 'C':
|
||||
sigp++;
|
||||
return new Type.SimpleType("char");
|
||||
|
||||
case 'D':
|
||||
sigp++;
|
||||
return new Type.SimpleType("double");
|
||||
|
||||
case 'F':
|
||||
sigp++;
|
||||
return new Type.SimpleType("float");
|
||||
|
||||
case 'I':
|
||||
sigp++;
|
||||
return new Type.SimpleType("int");
|
||||
|
||||
case 'J':
|
||||
sigp++;
|
||||
return new Type.SimpleType("long");
|
||||
|
||||
case 'L':
|
||||
return parseClassTypeSignature();
|
||||
|
||||
case 'S':
|
||||
sigp++;
|
||||
return new Type.SimpleType("short");
|
||||
|
||||
case 'T':
|
||||
return parseTypeVariableSignature();
|
||||
|
||||
case 'V':
|
||||
sigp++;
|
||||
return new Type.SimpleType("void");
|
||||
|
||||
case 'Z':
|
||||
sigp++;
|
||||
return new Type.SimpleType("boolean");
|
||||
|
||||
case '[':
|
||||
sigp++;
|
||||
return new Type.ArrayType(parseTypeSignature());
|
||||
|
||||
case '*':
|
||||
sigp++;
|
||||
return new Type.WildcardType();
|
||||
|
||||
case '+':
|
||||
sigp++;
|
||||
return new Type.WildcardType("extends", parseTypeSignature());
|
||||
|
||||
case '-':
|
||||
sigp++;
|
||||
return new Type.WildcardType("super", parseTypeSignature());
|
||||
|
||||
default:
|
||||
throw new IllegalStateException(debugInfo());
|
||||
}
|
||||
}
|
||||
|
||||
private List<Type> parseTypeSignatures(char term) {
|
||||
sigp++;
|
||||
List<Type> types = new ArrayList<Type>();
|
||||
while (sig.charAt(sigp) != term)
|
||||
types.add(parseTypeSignature());
|
||||
sigp++;
|
||||
return types;
|
||||
}
|
||||
|
||||
private Type parseClassTypeSignature() {
|
||||
assert sig.charAt(sigp) == 'L';
|
||||
sigp++;
|
||||
return parseClassTypeSignatureRest();
|
||||
}
|
||||
|
||||
private Type parseClassTypeSignatureRest() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Type t = null;
|
||||
char sigch;
|
||||
while (true) {
|
||||
switch (sigch = sig.charAt(sigp)) {
|
||||
case '/':
|
||||
sigp++;
|
||||
sb.append(".");
|
||||
break;
|
||||
|
||||
case '.':
|
||||
sigp++;
|
||||
if (t == null)
|
||||
t = new Type.SimpleType(sb.toString());
|
||||
return new Type.InnerClassType(t, parseClassTypeSignatureRest());
|
||||
|
||||
case ';':
|
||||
sigp++;
|
||||
if (t == null)
|
||||
t = new Type.SimpleType(sb.toString());
|
||||
return t;
|
||||
|
||||
case '<':
|
||||
List<Type> argTypes = parseTypeSignatures('>');
|
||||
t = new Type.ClassType(sb.toString(), argTypes);
|
||||
break;
|
||||
|
||||
default:
|
||||
sigp++;
|
||||
sb.append(sigch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Type> parseTypeArgTypes() {
|
||||
assert sig.charAt(sigp) == '<';
|
||||
sigp++;
|
||||
List<Type> types = null;
|
||||
types = new ArrayList<Type>();
|
||||
while (sig.charAt(sigp) != '>')
|
||||
types.add(parseTypeArgType());
|
||||
sigp++;
|
||||
return types;
|
||||
}
|
||||
|
||||
private Type parseTypeArgType() {
|
||||
int sep = sig.indexOf(":", sigp);
|
||||
String name = sig.substring(sigp, sep);
|
||||
Type classBound = null;
|
||||
List<Type> interfaceBounds = null;
|
||||
sigp = sep + 1;
|
||||
if (sig.charAt(sigp) != ':')
|
||||
classBound = parseTypeSignature();
|
||||
while (sig.charAt(sigp) == ':') {
|
||||
sigp++;
|
||||
if (interfaceBounds == null)
|
||||
interfaceBounds = new ArrayList<Type>();
|
||||
interfaceBounds.add(parseTypeSignature());
|
||||
}
|
||||
return new Type.TypeArgType(name, classBound, interfaceBounds);
|
||||
}
|
||||
|
||||
private Type parseTypeVariableSignature() {
|
||||
sigp++;
|
||||
int sep = sig.indexOf(';', sigp);
|
||||
Type t = new Type.SimpleType(sig.substring(sigp, sep));
|
||||
sigp = sep + 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
private String debugInfo() {
|
||||
return sig.substring(0, sigp) + "!" + sig.charAt(sigp) + "!" + sig.substring(sigp+1);
|
||||
}
|
||||
|
||||
private String sig;
|
||||
private int sigp;
|
||||
|
||||
private Type type;
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.9.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Signature_attribute extends Attribute {
|
||||
Signature_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
signature_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public Signature_attribute(ConstantPool constant_pool, int signature_index)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.Signature), signature_index);
|
||||
}
|
||||
|
||||
public Signature_attribute(int name_index, int signature_index) {
|
||||
super(name_index, 2);
|
||||
this.signature_index = signature_index;
|
||||
}
|
||||
|
||||
public String getSignature(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(signature_index);
|
||||
}
|
||||
|
||||
public Signature getParsedSignature() {
|
||||
return new Signature(signature_index);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitSignature(this, data);
|
||||
}
|
||||
|
||||
public final int signature_index;
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.15.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class SourceDebugExtension_attribute extends Attribute {
|
||||
SourceDebugExtension_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
debug_extension = new byte[attribute_length];
|
||||
cr.readFully(debug_extension);
|
||||
}
|
||||
|
||||
public SourceDebugExtension_attribute(ConstantPool constant_pool, byte[] debug_extension)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.SourceDebugExtension), debug_extension);
|
||||
}
|
||||
|
||||
public SourceDebugExtension_attribute(int name_index, byte[] debug_extension) {
|
||||
super(name_index, debug_extension.length);
|
||||
this.debug_extension = debug_extension;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
DataInputStream d = new DataInputStream(new ByteArrayInputStream(debug_extension));
|
||||
try {
|
||||
return d.readUTF();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitSourceDebugExtension(this, data);
|
||||
}
|
||||
|
||||
public final byte[] debug_extension;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.10.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class SourceFile_attribute extends Attribute {
|
||||
SourceFile_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
sourcefile_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public SourceFile_attribute(ConstantPool constant_pool, int sourcefile_index)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.SourceFile), sourcefile_index);
|
||||
}
|
||||
|
||||
public SourceFile_attribute(int name_index, int sourcefile_index) {
|
||||
super(name_index, 2);
|
||||
this.sourcefile_index = sourcefile_index;
|
||||
}
|
||||
|
||||
public String getSourceFile(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(sourcefile_index);
|
||||
}
|
||||
|
||||
public <R, P> R accept(Visitor<R, P> visitor, P p) {
|
||||
return visitor.visitSourceFile(this, p);
|
||||
}
|
||||
|
||||
public final int sourcefile_index;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2008 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class SourceID_attribute extends Attribute {
|
||||
|
||||
SourceID_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
sourceID_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
public SourceID_attribute(ConstantPool constant_pool, int sourceID_index)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.SourceID), sourceID_index);
|
||||
}
|
||||
|
||||
public SourceID_attribute(int name_index, int sourceID_index) {
|
||||
super(name_index, 2);
|
||||
this.sourceID_index = sourceID_index;
|
||||
}
|
||||
|
||||
String getSourceID(ConstantPool constant_pool) throws ConstantPoolException {
|
||||
return constant_pool.getUTF8Value(sourceID_index);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitSourceID(this, data);
|
||||
}
|
||||
|
||||
public final int sourceID_index;
|
||||
}
|
@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.4.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class StackMapTable_attribute extends Attribute {
|
||||
static class InvalidStackMap extends AttributeException {
|
||||
InvalidStackMap(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
|
||||
StackMapTable_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, InvalidStackMap {
|
||||
super(name_index, length);
|
||||
number_of_entries = cr.readUnsignedShort();
|
||||
entries = new stack_map_frame[number_of_entries];
|
||||
for (int i = 0; i < number_of_entries; i++)
|
||||
entries[i] = stack_map_frame.read(cr);
|
||||
}
|
||||
|
||||
public StackMapTable_attribute(ConstantPool constant_pool, stack_map_frame[] entries)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.StackMapTable), entries);
|
||||
}
|
||||
|
||||
public StackMapTable_attribute(int name_index, stack_map_frame[] entries) {
|
||||
super(name_index, length(entries));
|
||||
this.number_of_entries = entries.length;
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitStackMapTable(this, data);
|
||||
}
|
||||
|
||||
static int length(stack_map_frame[] entries) {
|
||||
int n = 2;
|
||||
for (stack_map_frame entry: entries)
|
||||
n += entry.length();
|
||||
return n;
|
||||
}
|
||||
|
||||
public final int number_of_entries;
|
||||
public final stack_map_frame entries[];
|
||||
|
||||
public static abstract class stack_map_frame {
|
||||
static stack_map_frame read(ClassReader cr)
|
||||
throws IOException, InvalidStackMap {
|
||||
int frame_type = cr.readUnsignedByte();
|
||||
if (frame_type <= 63)
|
||||
return new same_frame(frame_type);
|
||||
else if (frame_type <= 127)
|
||||
return new same_locals_1_stack_item_frame(frame_type, cr);
|
||||
else if (frame_type <= 246)
|
||||
throw new Error("unknown frame_type " + frame_type);
|
||||
else if (frame_type == 247)
|
||||
return new same_locals_1_stack_item_frame_extended(frame_type, cr);
|
||||
else if (frame_type <= 250)
|
||||
return new chop_frame(frame_type, cr);
|
||||
else if (frame_type == 251)
|
||||
return new same_frame_extended(frame_type, cr);
|
||||
else if (frame_type <= 254)
|
||||
return new append_frame(frame_type, cr);
|
||||
else
|
||||
return new full_frame(frame_type, cr);
|
||||
}
|
||||
|
||||
protected stack_map_frame(int frame_type) {
|
||||
this.frame_type = frame_type;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
|
||||
|
||||
public final int frame_type;
|
||||
|
||||
public static interface Visitor<R,P> {
|
||||
R visit_same_frame(same_frame frame, P p);
|
||||
R visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame frame, P p);
|
||||
R visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended frame, P p);
|
||||
R visit_chop_frame(chop_frame frame, P p);
|
||||
R visit_same_frame_extended(same_frame_extended frame, P p);
|
||||
R visit_append_frame(append_frame frame, P p);
|
||||
R visit_full_frame(full_frame frame, P p);
|
||||
}
|
||||
}
|
||||
|
||||
public static class same_frame extends stack_map_frame {
|
||||
same_frame(int frame_type) {
|
||||
super(frame_type);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visit_same_frame(this, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static class same_locals_1_stack_item_frame extends stack_map_frame {
|
||||
same_locals_1_stack_item_frame(int frame_type, ClassReader cr)
|
||||
throws IOException, InvalidStackMap {
|
||||
super(frame_type);
|
||||
stack = new verification_type_info[1];
|
||||
stack[0] = verification_type_info.read(cr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return super.length() + stack[0].length();
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visit_same_locals_1_stack_item_frame(this, data);
|
||||
}
|
||||
|
||||
public final verification_type_info[] stack;
|
||||
}
|
||||
|
||||
public static class same_locals_1_stack_item_frame_extended extends stack_map_frame {
|
||||
same_locals_1_stack_item_frame_extended(int frame_type, ClassReader cr)
|
||||
throws IOException, InvalidStackMap {
|
||||
super(frame_type);
|
||||
offset_delta = cr.readUnsignedShort();
|
||||
stack = new verification_type_info[1];
|
||||
stack[0] = verification_type_info.read(cr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return super.length() + 2 + stack[0].length();
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visit_same_locals_1_stack_item_frame_extended(this, data);
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
public final verification_type_info[] stack;
|
||||
}
|
||||
|
||||
public static class chop_frame extends stack_map_frame {
|
||||
chop_frame(int frame_type, ClassReader cr) throws IOException {
|
||||
super(frame_type);
|
||||
offset_delta = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return super.length() + 2;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visit_chop_frame(this, data);
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
}
|
||||
|
||||
public static class same_frame_extended extends stack_map_frame {
|
||||
same_frame_extended(int frame_type, ClassReader cr) throws IOException {
|
||||
super(frame_type);
|
||||
offset_delta = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return super.length() + 2;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visit_same_frame_extended(this, data);
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
}
|
||||
|
||||
public static class append_frame extends stack_map_frame {
|
||||
append_frame(int frame_type, ClassReader cr)
|
||||
throws IOException, InvalidStackMap {
|
||||
super(frame_type);
|
||||
offset_delta = cr.readUnsignedShort();
|
||||
locals = new verification_type_info[frame_type - 251];
|
||||
for (int i = 0; i < locals.length; i++)
|
||||
locals[i] = verification_type_info.read(cr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
int n = super.length() + 2;
|
||||
for (verification_type_info local: locals)
|
||||
n += local.length();
|
||||
return n;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visit_append_frame(this, data);
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
public final verification_type_info[] locals;
|
||||
}
|
||||
|
||||
public static class full_frame extends stack_map_frame {
|
||||
full_frame(int frame_type, ClassReader cr)
|
||||
throws IOException, InvalidStackMap {
|
||||
super(frame_type);
|
||||
offset_delta = cr.readUnsignedShort();
|
||||
number_of_locals = cr.readUnsignedShort();
|
||||
locals = new verification_type_info[number_of_locals];
|
||||
for (int i = 0; i < locals.length; i++)
|
||||
locals[i] = verification_type_info.read(cr);
|
||||
number_of_stack_items = cr.readUnsignedShort();
|
||||
stack = new verification_type_info[number_of_stack_items];
|
||||
for (int i = 0; i < stack.length; i++)
|
||||
stack[i] = verification_type_info.read(cr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
int n = super.length() + 2;
|
||||
for (verification_type_info local: locals)
|
||||
n += local.length();
|
||||
n += 2;
|
||||
for (verification_type_info item: stack)
|
||||
n += item.length();
|
||||
return n;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visit_full_frame(this, data);
|
||||
}
|
||||
|
||||
public final int offset_delta;
|
||||
public final int number_of_locals;
|
||||
public final verification_type_info[] locals;
|
||||
public final int number_of_stack_items;
|
||||
public final verification_type_info[] stack;
|
||||
}
|
||||
|
||||
public static class verification_type_info {
|
||||
public static final int ITEM_Top = 0;
|
||||
public static final int ITEM_Integer = 1;
|
||||
public static final int ITEM_Float = 2;
|
||||
public static final int ITEM_Long = 4;
|
||||
public static final int ITEM_Double = 3;
|
||||
public static final int ITEM_Null = 5;
|
||||
public static final int ITEM_UninitializedThis = 6;
|
||||
public static final int ITEM_Object = 7;
|
||||
public static final int ITEM_Uninitialized = 8;
|
||||
|
||||
static verification_type_info read(ClassReader cr)
|
||||
throws IOException, InvalidStackMap {
|
||||
int tag = cr.readUnsignedByte();
|
||||
switch (tag) {
|
||||
case ITEM_Top:
|
||||
case ITEM_Integer:
|
||||
case ITEM_Float:
|
||||
case ITEM_Long:
|
||||
case ITEM_Double:
|
||||
case ITEM_Null:
|
||||
case ITEM_UninitializedThis:
|
||||
return new verification_type_info(tag);
|
||||
|
||||
case ITEM_Object:
|
||||
return new Object_variable_info(cr);
|
||||
|
||||
case ITEM_Uninitialized:
|
||||
return new Uninitialized_variable_info(cr);
|
||||
|
||||
default:
|
||||
throw new InvalidStackMap("unrecognized verification_type_info tag");
|
||||
}
|
||||
}
|
||||
|
||||
verification_type_info(int tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public final int tag;
|
||||
}
|
||||
|
||||
public static class Object_variable_info extends verification_type_info {
|
||||
Object_variable_info(ClassReader cr) throws IOException {
|
||||
super(ITEM_Object);
|
||||
cpool_index = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return super.length() + 2;
|
||||
}
|
||||
|
||||
public final int cpool_index;
|
||||
}
|
||||
|
||||
public static class Uninitialized_variable_info extends verification_type_info {
|
||||
Uninitialized_variable_info(ClassReader cr) throws IOException {
|
||||
super(ITEM_Uninitialized);
|
||||
offset = cr.readUnsignedShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length() {
|
||||
return super.length() + 2;
|
||||
}
|
||||
|
||||
public final int offset;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class StackMap_attribute extends Attribute {
|
||||
StackMap_attribute(ClassReader cr, int name_index, int length)
|
||||
throws IOException, StackMapTable_attribute.InvalidStackMap {
|
||||
super(name_index, length);
|
||||
number_of_entries = cr.readUnsignedShort();
|
||||
entries = new stack_map_frame[number_of_entries];
|
||||
for (int i = 0; i < number_of_entries; i++)
|
||||
entries[i] = new stack_map_frame(cr);
|
||||
}
|
||||
|
||||
public StackMap_attribute(ConstantPool constant_pool, stack_map_frame[] entries)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.StackMap), entries);
|
||||
}
|
||||
|
||||
public StackMap_attribute(int name_index, stack_map_frame[] entries) {
|
||||
super(name_index, StackMapTable_attribute.length(entries));
|
||||
this.number_of_entries = entries.length;
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitStackMap(this, data);
|
||||
}
|
||||
|
||||
public final int number_of_entries;
|
||||
public final stack_map_frame entries[];
|
||||
|
||||
public static class stack_map_frame extends StackMapTable_attribute.full_frame {
|
||||
stack_map_frame(ClassReader cr)
|
||||
throws IOException, StackMapTable_attribute.InvalidStackMap {
|
||||
super(255, cr);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.classfile;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.8.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Synthetic_attribute extends Attribute {
|
||||
Synthetic_attribute(ClassReader cr, int name_index, int length) throws IOException {
|
||||
super(name_index, length);
|
||||
}
|
||||
|
||||
public Synthetic_attribute(ConstantPool constant_pool)
|
||||
throws ConstantPoolException {
|
||||
this(constant_pool.getUTF8Index(Attribute.Synthetic));
|
||||
}
|
||||
|
||||
public Synthetic_attribute(int name_index) {
|
||||
super(name_index, 0);
|
||||
}
|
||||
|
||||
public <R, D> R accept(Visitor<R, D> visitor, D data) {
|
||||
return visitor.visitSynthetic(this, data);
|
||||
}
|
||||
}
|
232
langtools/src/share/classes/com/sun/tools/classfile/Type.java
Normal file
232
langtools/src/share/classes/com/sun/tools/classfile/Type.java
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright 2008 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 com.sun.tools.classfile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Type {
|
||||
protected Type() { }
|
||||
|
||||
public boolean isObject() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static void append(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
|
||||
sb.append(prefix);
|
||||
String sep = "";
|
||||
for (Type t: types) {
|
||||
sb.append(sep);
|
||||
sb.append(t);
|
||||
sep = ", ";
|
||||
}
|
||||
sb.append(suffix);
|
||||
}
|
||||
|
||||
protected static void appendIfNotEmpty(StringBuilder sb, String prefix, List<? extends Type> types, String suffix) {
|
||||
if (types != null && types.size() > 0)
|
||||
append(sb, prefix, types, suffix);
|
||||
}
|
||||
|
||||
public static class SimpleType extends Type {
|
||||
public SimpleType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObject() {
|
||||
return name.equals("java.lang.Object");
|
||||
}
|
||||
|
||||
public final String name;
|
||||
}
|
||||
|
||||
public static class ArrayType extends Type {
|
||||
public ArrayType(Type elemType) {
|
||||
this.elemType = elemType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return elemType + "[]";
|
||||
}
|
||||
|
||||
public final Type elemType;
|
||||
}
|
||||
|
||||
public static class MethodType extends Type {
|
||||
public MethodType(List<? extends Type> argTypes, Type resultType) {
|
||||
this(null, argTypes, resultType, null);
|
||||
}
|
||||
|
||||
public MethodType(List<? extends Type> typeArgTypes,
|
||||
List<? extends Type> argTypes,
|
||||
Type returnType,
|
||||
List<? extends Type> throwsTypes) {
|
||||
this.typeArgTypes = typeArgTypes;
|
||||
this.argTypes = argTypes;
|
||||
this.returnType = returnType;
|
||||
this.throwsTypes = throwsTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendIfNotEmpty(sb, "<", typeArgTypes, "> ");
|
||||
sb.append(returnType);
|
||||
append(sb, " (", argTypes, ")");
|
||||
appendIfNotEmpty(sb, " throws ", throwsTypes, "");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public final List<? extends Type> typeArgTypes;
|
||||
public final List<? extends Type> argTypes;
|
||||
public final Type returnType;
|
||||
public final List<? extends Type> throwsTypes;
|
||||
}
|
||||
|
||||
public static class ClassSigType extends Type {
|
||||
public ClassSigType(List<Type> typeArgTypes, Type superclassType, List<Type> superinterfaceTypes) {
|
||||
this.typeArgTypes = typeArgTypes;
|
||||
this.superclassType = superclassType;
|
||||
this.superinterfaceTypes = superinterfaceTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
appendIfNotEmpty(sb, "<", typeArgTypes, ">");
|
||||
if (superclassType != null && !superclassType.isObject()) {
|
||||
sb.append(" extends ");
|
||||
sb.append(superclassType);
|
||||
}
|
||||
appendIfNotEmpty(sb, " implements ", superinterfaceTypes, "");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public final List<Type> typeArgTypes;
|
||||
public final Type superclassType;
|
||||
public final List<Type> superinterfaceTypes;
|
||||
}
|
||||
|
||||
public static class ClassType extends Type {
|
||||
public ClassType(String name, List<Type> typeArgs) {
|
||||
this.name = name;
|
||||
this.typeArgs = typeArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(name);
|
||||
appendIfNotEmpty(sb, "<", typeArgs, ">");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public final String name;
|
||||
public final List<Type> typeArgs;
|
||||
}
|
||||
|
||||
|
||||
public static class InnerClassType extends Type {
|
||||
public InnerClassType(Type outerType, Type innerType) {
|
||||
this.outerType = outerType;
|
||||
this.innerType = innerType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return outerType + "." + innerType;
|
||||
}
|
||||
|
||||
public final Type outerType;
|
||||
public final Type innerType;
|
||||
}
|
||||
|
||||
public static class TypeArgType extends Type {
|
||||
public TypeArgType(String name, Type classBound, List<Type> interfaceBounds) {
|
||||
this.name = name;
|
||||
this.classBound = classBound;
|
||||
this.interfaceBounds = interfaceBounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(name);
|
||||
String sep = " extends ";
|
||||
if (classBound != null && !classBound.isObject()) {
|
||||
sb.append(sep);
|
||||
sb.append(classBound);
|
||||
sep = " & ";
|
||||
}
|
||||
if (interfaceBounds != null) {
|
||||
for (Type bound: interfaceBounds) {
|
||||
sb.append(sep);
|
||||
sb.append(bound);
|
||||
sep = " & ";
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public final String name;
|
||||
public final Type classBound;
|
||||
public final List<Type> interfaceBounds;
|
||||
}
|
||||
|
||||
public static class WildcardType extends Type {
|
||||
public WildcardType() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
public WildcardType(String kind, Type boundType) {
|
||||
this.kind = kind;
|
||||
this.boundType = boundType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (kind == null)
|
||||
return "?";
|
||||
else
|
||||
return "? " + kind + " " + boundType;
|
||||
}
|
||||
|
||||
public final String kind;
|
||||
public final Type boundType;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
A minimalist library to read and write class files into objects closely
|
||||
based on the corresponding definitions in the Java Virtual Machine
|
||||
Specification (JVMS).
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.Annotation;
|
||||
import com.sun.tools.classfile.Annotation.Annotation_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Array_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Class_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Enum_element_value;
|
||||
import com.sun.tools.classfile.Annotation.Primitive_element_value;
|
||||
|
||||
/**
|
||||
* A writer for writing annotations as text.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class AnnotationWriter extends BasicWriter {
|
||||
static AnnotationWriter instance(Context context) {
|
||||
AnnotationWriter instance = context.get(AnnotationWriter.class);
|
||||
if (instance == null)
|
||||
instance = new AnnotationWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected AnnotationWriter(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public void write(Annotation annot) {
|
||||
print("#" + annot.type_index + "(");
|
||||
for (int i = 0; i < annot.num_element_value_pairs; i++) {
|
||||
if (i > 0)
|
||||
print(",");
|
||||
write(annot.element_value_pairs[i]);
|
||||
}
|
||||
print(")");
|
||||
}
|
||||
|
||||
public void write(Annotation.element_value_pair pair) {
|
||||
print("#" + pair.element_name_index + ":");
|
||||
write(pair.value);
|
||||
}
|
||||
|
||||
public void write(Annotation.element_value value) {
|
||||
ev_writer.write(value);
|
||||
}
|
||||
|
||||
element_value_Writer ev_writer = new element_value_Writer();
|
||||
|
||||
class element_value_Writer implements Annotation.element_value.Visitor<Void,Void> {
|
||||
public void write(Annotation.element_value value) {
|
||||
value.accept(this, null);
|
||||
}
|
||||
|
||||
public Void visitPrimitive(Primitive_element_value ev, Void p) {
|
||||
print(((char) ev.tag) + "#" + ev.const_value_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitEnum(Enum_element_value ev, Void p) {
|
||||
print(((char) ev.tag) + "#" + ev.type_name_index + ".#" + ev.const_name_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitClass(Class_element_value ev, Void p) {
|
||||
print(((char) ev.tag) + "#" + ev.class_info_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitAnnotation(Annotation_element_value ev, Void p) {
|
||||
print((char) ev.tag);
|
||||
AnnotationWriter.this.write(ev.annotation_value);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitArray(Array_element_value ev, Void p) {
|
||||
print("[");
|
||||
for (int i = 0; i < ev.num_values; i++) {
|
||||
if (i > 0)
|
||||
print(",");
|
||||
write(ev.values[i]);
|
||||
}
|
||||
print("]");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,679 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import java.util.Formatter;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
import com.sun.tools.classfile.AnnotationDefault_attribute;
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.Attributes;
|
||||
import com.sun.tools.classfile.CharacterRangeTable_attribute;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.CompilationID_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.ConstantValue_attribute;
|
||||
import com.sun.tools.classfile.DefaultAttribute;
|
||||
import com.sun.tools.classfile.Deprecated_attribute;
|
||||
import com.sun.tools.classfile.EnclosingMethod_attribute;
|
||||
import com.sun.tools.classfile.Exceptions_attribute;
|
||||
import com.sun.tools.classfile.Field;
|
||||
import com.sun.tools.classfile.InnerClasses_attribute;
|
||||
import com.sun.tools.classfile.LineNumberTable_attribute;
|
||||
import com.sun.tools.classfile.LocalVariableTable_attribute;
|
||||
import com.sun.tools.classfile.LocalVariableTypeTable_attribute;
|
||||
import com.sun.tools.classfile.ModuleExportTable_attribute;
|
||||
import com.sun.tools.classfile.ModuleMemberTable_attribute;
|
||||
import com.sun.tools.classfile.Module_attribute;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;
|
||||
import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute;
|
||||
import com.sun.tools.classfile.Signature_attribute;
|
||||
import com.sun.tools.classfile.SourceDebugExtension_attribute;
|
||||
import com.sun.tools.classfile.SourceFile_attribute;
|
||||
import com.sun.tools.classfile.SourceID_attribute;
|
||||
import com.sun.tools.classfile.StackMapTable_attribute;
|
||||
import com.sun.tools.classfile.StackMap_attribute;
|
||||
import com.sun.tools.classfile.Synthetic_attribute;
|
||||
|
||||
import static com.sun.tools.classfile.AccessFlags.*;
|
||||
|
||||
/*
|
||||
* A writer for writing Attributes as text.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class AttributeWriter extends BasicWriter
|
||||
implements Attribute.Visitor<Void,Void>
|
||||
{
|
||||
static AttributeWriter instance(Context context) {
|
||||
AttributeWriter instance = context.get(AttributeWriter.class);
|
||||
if (instance == null)
|
||||
instance = new AttributeWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected AttributeWriter(Context context) {
|
||||
super(context);
|
||||
context.put(AttributeWriter.class, this);
|
||||
annotationWriter = AnnotationWriter.instance(context);
|
||||
codeWriter = CodeWriter.instance(context);
|
||||
constantWriter = ConstantWriter.instance(context);
|
||||
options = Options.instance(context);
|
||||
}
|
||||
|
||||
public void write(Object owner, Attribute attr, ConstantPool constant_pool) {
|
||||
if (attr != null) {
|
||||
// null checks
|
||||
owner.getClass();
|
||||
constant_pool.getClass();
|
||||
this.constant_pool = constant_pool;
|
||||
this.owner = owner;
|
||||
attr.accept(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(Object owner, Attributes attrs, ConstantPool constant_pool) {
|
||||
if (attrs != null) {
|
||||
// null checks
|
||||
owner.getClass();
|
||||
constant_pool.getClass();
|
||||
this.constant_pool = constant_pool;
|
||||
this.owner = owner;
|
||||
for (Attribute attr: attrs)
|
||||
attr.accept(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitDefault(DefaultAttribute attr, Void ignore) {
|
||||
byte[] data = attr.info;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
print(" ");
|
||||
try {
|
||||
print(attr.getName(constant_pool));
|
||||
} catch (ConstantPoolException e) {
|
||||
report(e);
|
||||
print("attribute name = #" + attr.attribute_name_index);
|
||||
}
|
||||
print(": ");
|
||||
println("length = 0x" + toHex(attr.info.length));
|
||||
|
||||
print(" ");
|
||||
|
||||
while (i < data.length) {
|
||||
print(toHex(data[i], 2));
|
||||
|
||||
j++;
|
||||
if (j == 16) {
|
||||
println();
|
||||
print(" ");
|
||||
j = 0;
|
||||
} else {
|
||||
print(" ");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitAnnotationDefault(AnnotationDefault_attribute attr, Void ignore) {
|
||||
println(" AnnotationDefault: ");
|
||||
print(" default_value: ");
|
||||
annotationWriter.write(attr.default_value);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
|
||||
print(" CharacterRangeTable: ");
|
||||
for (int i = 0; i < attr.character_range_table.length; i++) {
|
||||
CharacterRangeTable_attribute.Entry e = attr.character_range_table[i];
|
||||
print(" " + e.start_pc + ", " +
|
||||
e.end_pc + ", " +
|
||||
Integer.toHexString(e.character_range_start) + ", " +
|
||||
Integer.toHexString(e.character_range_end) + ", " +
|
||||
Integer.toHexString(e.flags) +
|
||||
"\t// ");
|
||||
print(e.start_pc + ", " +
|
||||
e.end_pc + ", " +
|
||||
(e.character_range_start >> 10) + ":" + (e.character_range_start & 0x3ff) + ", " +
|
||||
(e.character_range_end >> 10) + ":" + (e.character_range_end & 0x3ff));
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_STATEMENT) != 0)
|
||||
print(", statement");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_BLOCK) != 0)
|
||||
print(", block");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_ASSIGNMENT) != 0)
|
||||
print(", assignment");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_CONTROLLER) != 0)
|
||||
print(", flow-controller");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_FLOW_TARGET) != 0)
|
||||
print(", flow-target");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_INVOKE) != 0)
|
||||
print(", invoke");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_CREATE) != 0)
|
||||
print(", create");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_TRUE) != 0)
|
||||
print(", branch-true");
|
||||
if ((e.flags & CharacterRangeTable_attribute.CRT_BRANCH_FALSE) != 0)
|
||||
print(", branch-false");
|
||||
|
||||
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitCode(Code_attribute attr, Void ignore) {
|
||||
codeWriter.write(attr, constant_pool);
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitCompilationID(CompilationID_attribute attr, Void ignore) {
|
||||
constantWriter.write(attr.compilationID_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitConstantValue(ConstantValue_attribute attr, Void ignore) {
|
||||
if (options.compat) // BUG 6622216 javap names some attributes incorrectly
|
||||
print(" Constant value: ");
|
||||
else
|
||||
print(" ConstantValue: ");
|
||||
constantWriter.write(attr.constantvalue_index);
|
||||
if (!options.compat) // BUG 6622232 javap gets whitespace confused
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitDeprecated(Deprecated_attribute attr, Void ignore) {
|
||||
if (!(options.compat && owner instanceof Field)) // BUG 6622232 javap gets whitespace confused
|
||||
print(" ");
|
||||
println("Deprecated: true");
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitEnclosingMethod(EnclosingMethod_attribute attr, Void ignore) {
|
||||
print(" EnclosingMethod: #" + attr.class_index + ".#" + attr.method_index
|
||||
+ "\t// " + getJavaClassName(attr));
|
||||
if (attr.method_index != 0)
|
||||
print("." + getMethodName(attr));
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getJavaClassName(EnclosingMethod_attribute a) {
|
||||
try {
|
||||
return getJavaName(a.getClassName(constant_pool));
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String getMethodName(EnclosingMethod_attribute a) {
|
||||
try {
|
||||
return a.getMethodName(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitExceptions(Exceptions_attribute attr, Void ignore) {
|
||||
println(" Exceptions: ");
|
||||
print(" throws ");
|
||||
for (int i = 0; i < attr.number_of_exceptions; i++) {
|
||||
if (i > 0)
|
||||
print(", ");
|
||||
print(getJavaException(attr, i));
|
||||
}
|
||||
if (!options.compat) // BUG 6622232 javap gets whitespace confused
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
String getJavaException(Exceptions_attribute attr, int index) {
|
||||
try {
|
||||
return getJavaName(attr.getException(index, constant_pool));
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitInnerClasses(InnerClasses_attribute attr, Void ignore) {
|
||||
boolean first = true;
|
||||
if (options.compat) {
|
||||
writeInnerClassHeader();
|
||||
first = false;
|
||||
}
|
||||
for (int i = 0 ; i < attr.classes.length; i++) {
|
||||
InnerClasses_attribute.Info info = attr.classes[i];
|
||||
//access
|
||||
AccessFlags access_flags = info.inner_class_access_flags;
|
||||
if (options.compat) {
|
||||
// BUG 6622215: javap ignores certain relevant access flags
|
||||
access_flags = access_flags.ignore(ACC_STATIC | ACC_PROTECTED | ACC_PRIVATE | ACC_INTERFACE | ACC_SYNTHETIC | ACC_ENUM);
|
||||
// BUG 6622232: javap gets whitespace confused
|
||||
print(" ");
|
||||
}
|
||||
if (options.checkAccess(access_flags)) {
|
||||
if (first) {
|
||||
writeInnerClassHeader();
|
||||
first = false;
|
||||
}
|
||||
if (!options.compat) // BUG 6622232: javap gets whitespace confused
|
||||
print(" ");
|
||||
for (String name: access_flags.getInnerClassModifiers())
|
||||
print(name + " ");
|
||||
if (info.inner_name_index!=0) {
|
||||
print("#" + info.inner_name_index + "= ");
|
||||
}
|
||||
print("#" + info.inner_class_info_index);
|
||||
if (info.outer_class_info_index != 0) {
|
||||
print(" of #" + info.outer_class_info_index);
|
||||
}
|
||||
print("; //");
|
||||
if (info.inner_name_index != 0) {
|
||||
print(getInnerName(constant_pool, info) + "=");
|
||||
}
|
||||
constantWriter.write(info.inner_class_info_index);
|
||||
if (info.outer_class_info_index != 0) {
|
||||
print(" of ");
|
||||
constantWriter.write(info.outer_class_info_index);
|
||||
}
|
||||
println();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String getInnerName(ConstantPool constant_pool, InnerClasses_attribute.Info info) {
|
||||
try {
|
||||
return info.getInnerName(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeInnerClassHeader() {
|
||||
print(" ");
|
||||
if (options.compat) // BUG 6622216: javap names some attributes incorrectly
|
||||
print("InnerClass");
|
||||
else
|
||||
print("InnerClasses");
|
||||
println(": ");
|
||||
}
|
||||
|
||||
public Void visitLineNumberTable(LineNumberTable_attribute attr, Void ignore) {
|
||||
println(" LineNumberTable: ");
|
||||
for (LineNumberTable_attribute.Entry entry: attr.line_number_table) {
|
||||
println(" line " + entry.line_number + ": " + entry.start_pc);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitLocalVariableTable(LocalVariableTable_attribute attr, Void ignore) {
|
||||
println(" LocalVariableTable: ");
|
||||
println(" Start Length Slot Name Signature");
|
||||
|
||||
for (LocalVariableTable_attribute.Entry entry : attr.local_variable_table) {
|
||||
Formatter formatter = new Formatter();
|
||||
println(formatter.format("%8d %7d %5d %5s %s",
|
||||
entry.start_pc, entry.length, entry.index,
|
||||
constantWriter.stringValue(entry.name_index),
|
||||
constantWriter.stringValue(entry.descriptor_index)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr, Void ignore) {
|
||||
println(" LocalVariableTypeTable: ");
|
||||
println(" Start Length Slot Name Signature");
|
||||
|
||||
for (LocalVariableTypeTable_attribute.Entry entry : attr.local_variable_table) {
|
||||
Formatter formatter = new Formatter();
|
||||
println(formatter.format("%8d %7d %5d %5s %s",
|
||||
entry.start_pc, entry.length, entry.index,
|
||||
constantWriter.stringValue(entry.name_index),
|
||||
constantWriter.stringValue(entry.signature_index)));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitModule(Module_attribute attr, Void ignore) {
|
||||
println(" Module: #" + attr.module_name + "\t// " + getModuleName(attr));
|
||||
return null;
|
||||
}
|
||||
|
||||
String getModuleName(Module_attribute attr) {
|
||||
try {
|
||||
return attr.getModuleName(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitModuleExportTable(ModuleExportTable_attribute attr, Void ignore) {
|
||||
println(" ModuleExportTable:");
|
||||
println(" Types: (" + attr.export_type_table.length + ")");
|
||||
for (int i = 0; i < attr.export_type_table.length; i++) {
|
||||
println(" #" + attr.export_type_table[i] + "\t// " + getExportTypeName(attr, i));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String getExportTypeName(ModuleExportTable_attribute attr, int index) {
|
||||
try {
|
||||
return attr.getExportTypeName(index, constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitModuleMemberTable(ModuleMemberTable_attribute attr, Void ignore) {
|
||||
println(" ModuleMemberTable:");
|
||||
println(" Packages: (" + attr.package_member_table.length + ")");
|
||||
for (int i = 0; i < attr.package_member_table.length; i++) {
|
||||
println(" #" + attr.package_member_table[i] + "\t// " + getPackageMemberName(attr, i));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String getPackageMemberName(ModuleMemberTable_attribute attr, int index) {
|
||||
try {
|
||||
return attr.getPackageMemberName(index, constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeVisibleAnnotations: ");
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(" " + i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeInvisibleAnnotations: ");
|
||||
for (int i = 0; i < attr.annotations.length; i++) {
|
||||
print(" " + i + ": ");
|
||||
annotationWriter.write(attr.annotations[i]);
|
||||
println();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeVisibleParameterAnnotations: ");
|
||||
for (int param = 0; param < attr.parameter_annotations.length; param++) {
|
||||
println(" parameter " + param + ": ");
|
||||
for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
|
||||
print(" " + i + ": ");
|
||||
annotationWriter.write(attr.parameter_annotations[param][i]);
|
||||
println();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, Void ignore) {
|
||||
println(" RuntimeInvisibleParameterAnnotations: ");
|
||||
for (int param = 0; param < attr.parameter_annotations.length; param++) {
|
||||
println(" " + param + ": ");
|
||||
for (int i = 0; i < attr.parameter_annotations[param].length; i++) {
|
||||
print(" " + i + ": ");
|
||||
annotationWriter.write(attr.parameter_annotations[param][i]);
|
||||
println();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitSignature(Signature_attribute attr, Void ignore) {
|
||||
println(" Signature: #" + attr.signature_index + "\t// " + getSignature(attr));
|
||||
return null;
|
||||
}
|
||||
|
||||
String getSignature(Signature_attribute info) {
|
||||
try {
|
||||
return info.getSignature(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr, Void ignore) {
|
||||
println(" SourceDebugExtension: " + attr.getValue());
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitSourceFile(SourceFile_attribute attr, Void ignore) {
|
||||
println(" SourceFile: \"" + getSourceFile(attr) + "\"");
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getSourceFile(SourceFile_attribute attr) {
|
||||
try {
|
||||
return attr.getSourceFile(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitSourceID(SourceID_attribute attr, Void ignore) {
|
||||
constantWriter.write(attr.sourceID_index);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitStackMap(StackMap_attribute attr, Void ignore) {
|
||||
println(" StackMap: number_of_entries = " + attr.number_of_entries);
|
||||
|
||||
StackMapTableWriter w = new StackMapTableWriter();
|
||||
for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
|
||||
w.write(entry);
|
||||
}
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visitStackMapTable(StackMapTable_attribute attr, Void ignore) {
|
||||
println(" StackMapTable: number_of_entries = " + attr.number_of_entries);
|
||||
|
||||
StackMapTableWriter w = new StackMapTableWriter();
|
||||
for (StackMapTable_attribute.stack_map_frame entry : attr.entries) {
|
||||
w.write(entry);
|
||||
}
|
||||
println();
|
||||
return null;
|
||||
}
|
||||
|
||||
class StackMapTableWriter // also handles CLDC StackMap attributes
|
||||
implements StackMapTable_attribute.stack_map_frame.Visitor<Void,Void> {
|
||||
public void write(StackMapTable_attribute.stack_map_frame frame) {
|
||||
frame.accept(this, null);
|
||||
}
|
||||
|
||||
public Void visit_same_frame(StackMapTable_attribute.same_frame frame, Void p) {
|
||||
printHeader(frame);
|
||||
println(" /* same */");
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_same_locals_1_stack_item_frame(StackMapTable_attribute.same_locals_1_stack_item_frame frame, Void p) {
|
||||
printHeader(frame);
|
||||
println(" /* same_locals_1_stack_item */");
|
||||
printMap("stack", frame.stack);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_same_locals_1_stack_item_frame_extended(StackMapTable_attribute.same_locals_1_stack_item_frame_extended frame, Void p) {
|
||||
printHeader(frame);
|
||||
println(" /* same_locals_1_stack_item_frame_extended */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
printMap("stack", frame.stack);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_chop_frame(StackMapTable_attribute.chop_frame frame, Void p) {
|
||||
printHeader(frame);
|
||||
println(" /* chop */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_same_frame_extended(StackMapTable_attribute.same_frame_extended frame, Void p) {
|
||||
printHeader(frame);
|
||||
println(" /* same_frame_extended */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_append_frame(StackMapTable_attribute.append_frame frame, Void p) {
|
||||
printHeader(frame);
|
||||
println(" /* append */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
printMap("locals", frame.locals);
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit_full_frame(StackMapTable_attribute.full_frame frame, Void p) {
|
||||
printHeader(frame);
|
||||
if (frame instanceof StackMap_attribute.stack_map_frame) {
|
||||
println(" offset = " + frame.offset_delta);
|
||||
} else {
|
||||
println(" /* full_frame */");
|
||||
println(" offset_delta = " + frame.offset_delta);
|
||||
}
|
||||
printMap("locals", frame.locals);
|
||||
printMap("stack", frame.stack);
|
||||
return null;
|
||||
}
|
||||
|
||||
void printHeader(StackMapTable_attribute.stack_map_frame frame) {
|
||||
print(" frame_type = " + frame.frame_type);
|
||||
}
|
||||
|
||||
void printMap(String name, StackMapTable_attribute.verification_type_info[] map) {
|
||||
print(" " + name + " = [");
|
||||
for (int i = 0; i < map.length; i++) {
|
||||
StackMapTable_attribute.verification_type_info info = map[i];
|
||||
int tag = info.tag;
|
||||
switch (tag) {
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Object:
|
||||
print(" ");
|
||||
constantWriter.write(((StackMapTable_attribute.Object_variable_info) info).cpool_index);
|
||||
break;
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:
|
||||
print(" " + mapTypeName(tag));
|
||||
print(" " + ((StackMapTable_attribute.Uninitialized_variable_info) info).offset);
|
||||
break;
|
||||
default:
|
||||
print(" " + mapTypeName(tag));
|
||||
}
|
||||
print(i == (map.length - 1) ? " " : ",");
|
||||
}
|
||||
println("]");
|
||||
}
|
||||
|
||||
String mapTypeName(int tag) {
|
||||
switch (tag) {
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Top:
|
||||
return "top";
|
||||
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Integer:
|
||||
return "int";
|
||||
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Float:
|
||||
return "float";
|
||||
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Long:
|
||||
return "long";
|
||||
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Double:
|
||||
return "double";
|
||||
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Null:
|
||||
return "null";
|
||||
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis:
|
||||
return "this";
|
||||
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Object:
|
||||
return "CP";
|
||||
|
||||
case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:
|
||||
return "uninitialized";
|
||||
|
||||
default:
|
||||
report("unrecognized verification_type_info tag: " + tag);
|
||||
return "[tag:" + tag + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Void visitSynthetic(Synthetic_attribute attr, Void ignore) {
|
||||
println("Synthetic: true");
|
||||
return null;
|
||||
}
|
||||
|
||||
static String getJavaName(String name) {
|
||||
return name.replace('/', '.');
|
||||
}
|
||||
|
||||
String toHex(byte b, int w) {
|
||||
if (options.compat) // BUG 6622260: javap prints negative bytes incorrectly in hex
|
||||
return toHex((int) b, w);
|
||||
else
|
||||
return toHex(b & 0xff, w);
|
||||
}
|
||||
|
||||
static String toHex(int i) {
|
||||
return Integer.toString(i, 16).toUpperCase();
|
||||
}
|
||||
|
||||
static String toHex(int i, int w) {
|
||||
String s = Integer.toHexString(i).toUpperCase();
|
||||
while (s.length() < w)
|
||||
s = "0" + s;
|
||||
return s.toUpperCase();
|
||||
}
|
||||
|
||||
private AnnotationWriter annotationWriter;
|
||||
private CodeWriter codeWriter;
|
||||
private ConstantWriter constantWriter;
|
||||
private Options options;
|
||||
|
||||
private ConstantPool constant_pool;
|
||||
private Object owner;
|
||||
}
|
131
langtools/src/share/classes/com/sun/tools/javap/BasicWriter.java
Normal file
131
langtools/src/share/classes/com/sun/tools/javap/BasicWriter.java
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import com.sun.tools.classfile.AttributeException;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.DescriptorException;
|
||||
|
||||
/*
|
||||
* A writer similar to a PrintWriter but which does not hide exceptions.
|
||||
* The standard print calls are line-buffered; report calls write messages directly.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class BasicWriter {
|
||||
protected BasicWriter(Context context) {
|
||||
lineWriter = LineWriter.instance(context);
|
||||
out = context.get(PrintWriter.class);
|
||||
}
|
||||
|
||||
protected void print(String s) {
|
||||
lineWriter.print(s);
|
||||
}
|
||||
|
||||
protected void print(Object o) {
|
||||
lineWriter.print(o == null ? null : o.toString());
|
||||
}
|
||||
|
||||
protected void println() {
|
||||
lineWriter.println();
|
||||
}
|
||||
|
||||
protected void println(String s) {
|
||||
lineWriter.print(s);
|
||||
lineWriter.println();
|
||||
}
|
||||
|
||||
protected void println(Object o) {
|
||||
lineWriter.print(o == null ? null : o.toString());
|
||||
lineWriter.println();
|
||||
}
|
||||
|
||||
protected String report(AttributeException e) {
|
||||
out.println("Error: " + e.getMessage()); // i18n?
|
||||
return "???";
|
||||
}
|
||||
|
||||
protected String report(ConstantPoolException e) {
|
||||
out.println("Error: " + e.getMessage()); // i18n?
|
||||
return "???";
|
||||
}
|
||||
|
||||
protected String report(DescriptorException e) {
|
||||
out.println("Error: " + e.getMessage()); // i18n?
|
||||
return "???";
|
||||
}
|
||||
|
||||
protected String report(String msg) {
|
||||
out.println("Error: " + msg); // i18n?
|
||||
return "???";
|
||||
}
|
||||
|
||||
private LineWriter lineWriter;
|
||||
private PrintWriter out;
|
||||
|
||||
private static class LineWriter {
|
||||
static LineWriter instance(Context context) {
|
||||
LineWriter instance = context.get(LineWriter.class);
|
||||
if (instance == null)
|
||||
instance = new LineWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected LineWriter(Context context) {
|
||||
context.put(LineWriter.class, this);
|
||||
out = context.get(PrintWriter.class);
|
||||
buffer = new StringBuilder();
|
||||
}
|
||||
|
||||
protected void print(String s) {
|
||||
if (s == null)
|
||||
s = "null";
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '\n') {
|
||||
println();
|
||||
} else {
|
||||
buffer.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void println() {
|
||||
out.println(buffer);
|
||||
buffer.setLength(0);
|
||||
}
|
||||
|
||||
private PrintWriter out;
|
||||
private StringBuilder buffer;
|
||||
}
|
||||
}
|
||||
|
488
langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java
Normal file
488
langtools/src/share/classes/com/sun/tools/javap/ClassWriter.java
Normal file
@ -0,0 +1,488 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.Attributes;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.Descriptor;
|
||||
import com.sun.tools.classfile.DescriptorException;
|
||||
import com.sun.tools.classfile.Exceptions_attribute;
|
||||
import com.sun.tools.classfile.Field;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import com.sun.tools.classfile.Signature;
|
||||
import com.sun.tools.classfile.Signature_attribute;
|
||||
import com.sun.tools.classfile.SourceFile_attribute;
|
||||
import com.sun.tools.classfile.Type;
|
||||
|
||||
import static com.sun.tools.classfile.AccessFlags.*;
|
||||
|
||||
/*
|
||||
* The main javap class to write the contents of a class file as text.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ClassWriter extends BasicWriter {
|
||||
static ClassWriter instance(Context context) {
|
||||
ClassWriter instance = context.get(ClassWriter.class);
|
||||
if (instance == null)
|
||||
instance = new ClassWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected ClassWriter(Context context) {
|
||||
super(context);
|
||||
context.put(ClassWriter.class, this);
|
||||
options = Options.instance(context);
|
||||
attrWriter = AttributeWriter.instance(context);
|
||||
codeWriter = CodeWriter.instance(context);
|
||||
constantWriter = ConstantWriter.instance(context);
|
||||
}
|
||||
|
||||
ClassFile getClassFile() {
|
||||
return classFile;
|
||||
}
|
||||
|
||||
Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void write(ClassFile cf) {
|
||||
classFile = cf;
|
||||
constant_pool = classFile.constant_pool;
|
||||
|
||||
Attribute sfa = cf.getAttribute(Attribute.SourceFile);
|
||||
if (sfa instanceof SourceFile_attribute) {
|
||||
println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\"");
|
||||
}
|
||||
|
||||
String name = getJavaName(classFile);
|
||||
AccessFlags flags = cf.access_flags;
|
||||
|
||||
writeModifiers(flags.getClassModifiers());
|
||||
|
||||
if (classFile.isClass())
|
||||
print("class ");
|
||||
else if (classFile.isInterface())
|
||||
print("interface ");
|
||||
|
||||
print(name);
|
||||
|
||||
Signature_attribute sigAttr = getSignature(cf.attributes);
|
||||
if (sigAttr == null) {
|
||||
// use info from class file header
|
||||
if (classFile.isClass()) {
|
||||
if (classFile.super_class != 0 ) {
|
||||
String sn = getJavaSuperclassName(cf);
|
||||
if (!sn.equals("java.lang.Object") || options.compat) { // BUG XXXXXXXX
|
||||
print(" extends ");
|
||||
print(sn);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < classFile.interfaces.length; i++) {
|
||||
print(i == 0 ? (classFile.isClass() ? " implements " : " extends ") : ",");
|
||||
print(getJavaInterfaceName(classFile, i));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Type t = sigAttr.getParsedSignature().getType(constant_pool);
|
||||
// The signature parser cannot disambiguate between a
|
||||
// FieldType and a ClassSignatureType that only contains a superclass type.
|
||||
if (t instanceof Type.ClassSigType)
|
||||
print(t);
|
||||
else if (!t.isObject()) {
|
||||
print(" extends ");
|
||||
print(t);
|
||||
}
|
||||
} catch (ConstantPoolException e) {
|
||||
print(report(e));
|
||||
}
|
||||
}
|
||||
|
||||
if (options.verbose) {
|
||||
println();
|
||||
attrWriter.write(cf, cf.attributes, constant_pool);
|
||||
println(" minor version: " + cf.minor_version);
|
||||
println(" major version: " + cf.major_version);
|
||||
if (!options.compat)
|
||||
writeList(" flags: ", flags.getClassFlags(), NEWLINE);
|
||||
constantWriter.writeConstantPool();
|
||||
println();
|
||||
} else {
|
||||
if (!options.compat)
|
||||
print(" ");
|
||||
}
|
||||
|
||||
println("{");
|
||||
writeFields();
|
||||
writeMethods();
|
||||
println("}");
|
||||
println();
|
||||
}
|
||||
|
||||
void writeFields() {
|
||||
for (Field f: classFile.fields) {
|
||||
writeField(f);
|
||||
}
|
||||
}
|
||||
|
||||
void writeField(Field f) {
|
||||
if (!options.checkAccess(f.access_flags))
|
||||
return;
|
||||
|
||||
if (!(options.showLineAndLocalVariableTables
|
||||
|| options.showDisassembled
|
||||
|| options.verbose
|
||||
|| options.showInternalSignatures
|
||||
|| options.showAllAttrs)) {
|
||||
print(" ");
|
||||
}
|
||||
|
||||
AccessFlags flags = f.access_flags;
|
||||
writeModifiers(flags.getFieldModifiers());
|
||||
Signature_attribute sigAttr = getSignature(f.attributes);
|
||||
if (sigAttr == null)
|
||||
print(getFieldType(f.descriptor));
|
||||
else {
|
||||
try {
|
||||
Type t = sigAttr.getParsedSignature().getType(constant_pool);
|
||||
print(t);
|
||||
} catch (ConstantPoolException e) {
|
||||
// report error?
|
||||
// fall back on non-generic descriptor
|
||||
print(getFieldType(f.descriptor));
|
||||
}
|
||||
}
|
||||
print(" ");
|
||||
print(getFieldName(f));
|
||||
print(";");
|
||||
println();
|
||||
|
||||
if (options.showInternalSignatures)
|
||||
println(" Signature: " + getValue(f.descriptor));
|
||||
|
||||
if (options.verbose && !options.compat)
|
||||
writeList(" flags: ", flags.getFieldFlags(), NEWLINE);
|
||||
|
||||
if (options.showAllAttrs) {
|
||||
for (Attribute attr: f.attributes)
|
||||
attrWriter.write(f, attr, constant_pool);
|
||||
println();
|
||||
}
|
||||
|
||||
if (options.showDisassembled || options.showLineAndLocalVariableTables)
|
||||
println();
|
||||
}
|
||||
|
||||
void writeMethods() {
|
||||
for (Method m: classFile.methods)
|
||||
writeMethod(m);
|
||||
}
|
||||
|
||||
void writeMethod(Method m) {
|
||||
if (!options.checkAccess(m.access_flags))
|
||||
return;
|
||||
|
||||
method = m;
|
||||
|
||||
if (!(options.showLineAndLocalVariableTables
|
||||
|| options.showDisassembled
|
||||
|| options.verbose
|
||||
|| options.showInternalSignatures
|
||||
|| options.showAllAttrs)) {
|
||||
print(" ");
|
||||
}
|
||||
|
||||
AccessFlags flags = m.access_flags;
|
||||
|
||||
Descriptor d;
|
||||
Type.MethodType methodType;
|
||||
List<? extends Type> methodExceptions;
|
||||
|
||||
Signature_attribute sigAttr = getSignature(m.attributes);
|
||||
if (sigAttr == null) {
|
||||
d = m.descriptor;
|
||||
methodType = null;
|
||||
methodExceptions = null;
|
||||
} else {
|
||||
Signature methodSig = sigAttr.getParsedSignature();
|
||||
d = methodSig;
|
||||
try {
|
||||
methodType = (Type.MethodType) methodSig.getType(constant_pool);
|
||||
methodExceptions = methodType.throwsTypes;
|
||||
if (methodExceptions != null && methodExceptions.size() == 0)
|
||||
methodExceptions = null;
|
||||
} catch (ConstantPoolException e) {
|
||||
// report error?
|
||||
// fall back on standard descriptor
|
||||
methodType = null;
|
||||
methodExceptions = null;
|
||||
}
|
||||
}
|
||||
|
||||
writeModifiers(flags.getMethodModifiers());
|
||||
if (methodType != null) {
|
||||
writeListIfNotEmpty("<", methodType.typeArgTypes, "> ");
|
||||
}
|
||||
if (getName(m).equals("<init>")) {
|
||||
print(getJavaName(classFile));
|
||||
print(getParameterTypes(d, flags));
|
||||
} else if (getName(m).equals("<clinit>")) {
|
||||
print("{}");
|
||||
} else {
|
||||
print(getReturnType(d));
|
||||
print(" ");
|
||||
print(getName(m));
|
||||
print(getParameterTypes(d, flags));
|
||||
}
|
||||
|
||||
Attribute e_attr = m.attributes.get(Attribute.Exceptions);
|
||||
if (e_attr != null) { // if there are generic exceptions, there must be erased exceptions
|
||||
if (e_attr instanceof Exceptions_attribute) {
|
||||
Exceptions_attribute exceptions = (Exceptions_attribute) e_attr;
|
||||
if (options.compat) { // Bug XXXXXXX whitespace
|
||||
if (!(options.showLineAndLocalVariableTables
|
||||
|| options.showDisassembled
|
||||
|| options.verbose
|
||||
|| options.showInternalSignatures
|
||||
|| options.showAllAttrs)) {
|
||||
print(" ");
|
||||
}
|
||||
print(" ");
|
||||
}
|
||||
print(" throws ");
|
||||
if (methodExceptions != null) { // use generic list if available
|
||||
writeList("", methodExceptions, "");
|
||||
} else {
|
||||
for (int i = 0; i < exceptions.number_of_exceptions; i++) {
|
||||
if (i > 0)
|
||||
print(", ");
|
||||
print(attrWriter.getJavaException(exceptions, i));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
report("Unexpected or invalid value for Exceptions attribute");
|
||||
}
|
||||
}
|
||||
|
||||
print(";");
|
||||
println();
|
||||
|
||||
if (options.showInternalSignatures)
|
||||
println(" Signature: " + getValue(m.descriptor));
|
||||
|
||||
if (options.verbose && !options.compat)
|
||||
writeList(" flags: ", flags.getMethodFlags(), NEWLINE);
|
||||
|
||||
Code_attribute code = null;
|
||||
Attribute c_attr = m.attributes.get(Attribute.Code);
|
||||
if (c_attr != null) {
|
||||
if (c_attr instanceof Code_attribute)
|
||||
code = (Code_attribute) c_attr;
|
||||
else
|
||||
report("Unexpected or invalid value for Code attribute");
|
||||
}
|
||||
|
||||
if (options.showDisassembled && !options.showAllAttrs) {
|
||||
if (code != null) {
|
||||
println(" Code:");
|
||||
codeWriter.writeInstrs(code);
|
||||
codeWriter.writeExceptionTable(code);
|
||||
}
|
||||
println();
|
||||
}
|
||||
|
||||
if (options.showLineAndLocalVariableTables) {
|
||||
if (code != null)
|
||||
attrWriter.write(code, code.attributes.get(Attribute.LineNumberTable), constant_pool);
|
||||
println();
|
||||
if (code != null)
|
||||
attrWriter.write(code, code.attributes.get(Attribute.LocalVariableTable), constant_pool);
|
||||
println();
|
||||
println();
|
||||
}
|
||||
|
||||
if (options.showAllAttrs) {
|
||||
Attribute[] attrs = m.attributes.attrs;
|
||||
for (Attribute attr: attrs)
|
||||
attrWriter.write(m, attr, constant_pool);
|
||||
|
||||
// // the following condition is to mimic old javap
|
||||
// if (!(attrs.length > 0 &&
|
||||
// attrs[attrs.length - 1] instanceof Exceptions_attribute))
|
||||
println();
|
||||
}
|
||||
}
|
||||
|
||||
void writeModifiers(Collection<String> items) {
|
||||
for (Object item: items) {
|
||||
print(item);
|
||||
print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void writeList(String prefix, Collection<?> items, String suffix) {
|
||||
print(prefix);
|
||||
String sep = "";
|
||||
for (Object item: items) {
|
||||
print(sep);
|
||||
print(item);
|
||||
sep = ", ";
|
||||
}
|
||||
print(suffix);
|
||||
}
|
||||
|
||||
void writeListIfNotEmpty(String prefix, List<?> items, String suffix) {
|
||||
if (items != null && items.size() > 0)
|
||||
writeList(prefix, items, suffix);
|
||||
}
|
||||
|
||||
Signature_attribute getSignature(Attributes attributes) {
|
||||
if (options.compat) // javap does not recognize recent attributes
|
||||
return null;
|
||||
return (Signature_attribute) attributes.get(Attribute.Signature);
|
||||
}
|
||||
|
||||
String adjustVarargs(AccessFlags flags, String params) {
|
||||
if (flags.is(ACC_VARARGS) && !options.compat) {
|
||||
int i = params.lastIndexOf("[]");
|
||||
if (i > 0)
|
||||
return params.substring(0, i) + "..." + params.substring(i+2);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
String getJavaName(ClassFile cf) {
|
||||
try {
|
||||
return getJavaName(cf.getName());
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getJavaSuperclassName(ClassFile cf) {
|
||||
try {
|
||||
return getJavaName(cf.getSuperclassName());
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getJavaInterfaceName(ClassFile cf, int index) {
|
||||
try {
|
||||
return getJavaName(cf.getInterfaceName(index));
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getFieldType(Descriptor d) {
|
||||
try {
|
||||
return d.getFieldType(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
} catch (DescriptorException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getReturnType(Descriptor d) {
|
||||
try {
|
||||
return d.getReturnType(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
} catch (DescriptorException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getParameterTypes(Descriptor d, AccessFlags flags) {
|
||||
try {
|
||||
return adjustVarargs(flags, d.getParameterTypes(constant_pool));
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
} catch (DescriptorException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getValue(Descriptor d) {
|
||||
try {
|
||||
return d.getValue(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getFieldName(Field f) {
|
||||
try {
|
||||
return f.getName(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getName(Method m) {
|
||||
try {
|
||||
return m.getName(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
static String getJavaName(String name) {
|
||||
return name.replace('/', '.');
|
||||
}
|
||||
|
||||
String getSourceFile(SourceFile_attribute attr) {
|
||||
try {
|
||||
return attr.getSourceFile(constant_pool);
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Options options;
|
||||
private AttributeWriter attrWriter;
|
||||
private CodeWriter codeWriter;
|
||||
private ConstantWriter constantWriter;
|
||||
private ClassFile classFile;
|
||||
private ConstantPool constant_pool;
|
||||
private Method method;
|
||||
private static final String NEWLINE = System.getProperty("line.separator", "\n");
|
||||
}
|
344
langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java
Normal file
344
langtools/src/share/classes/com/sun/tools/javap/CodeWriter.java
Normal file
@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
import com.sun.tools.classfile.DescriptorException;
|
||||
import com.sun.tools.classfile.Method;
|
||||
|
||||
import static com.sun.tools.classfile.OpCodes.*;
|
||||
|
||||
/*
|
||||
* Write the contents of a Code attribute.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
class CodeWriter extends BasicWriter {
|
||||
static CodeWriter instance(Context context) {
|
||||
CodeWriter instance = context.get(CodeWriter.class);
|
||||
if (instance == null)
|
||||
instance = new CodeWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected CodeWriter(Context context) {
|
||||
super(context);
|
||||
context.put(CodeWriter.class, this);
|
||||
attrWriter = AttributeWriter.instance(context);
|
||||
classWriter = ClassWriter.instance(context);
|
||||
constantWriter = ConstantWriter.instance(context);
|
||||
}
|
||||
|
||||
void write(Code_attribute attr, ConstantPool constant_pool) {
|
||||
println(" Code:");
|
||||
writeVerboseHeader(attr, constant_pool);
|
||||
writeInstrs(attr);
|
||||
writeExceptionTable(attr);
|
||||
attrWriter.write(attr, attr.attributes, constant_pool);
|
||||
}
|
||||
|
||||
public void writeVerboseHeader(Code_attribute attr, ConstantPool constant_pool) {
|
||||
Method method = classWriter.getMethod();
|
||||
String argCount;
|
||||
try {
|
||||
int n = method.descriptor.getParameterCount(constant_pool);
|
||||
if (!method.access_flags.is(AccessFlags.ACC_STATIC))
|
||||
++n; // for 'this'
|
||||
argCount = Integer.toString(n);
|
||||
} catch (ConstantPoolException e) {
|
||||
argCount = report(e);
|
||||
} catch (DescriptorException e) {
|
||||
argCount = report(e);
|
||||
}
|
||||
|
||||
println(" Stack=" + attr.max_stack +
|
||||
", Locals=" + attr.max_locals +
|
||||
", Args_size=" + argCount);
|
||||
|
||||
}
|
||||
|
||||
public void writeInstrs(Code_attribute attr) {
|
||||
try {
|
||||
for (int pc = 0; pc < attr.code_length;) {
|
||||
print(" " + pc + ":\t");
|
||||
pc += writeInstr(attr, pc);
|
||||
println();
|
||||
}
|
||||
} catch (Code_attribute.InvalidIndex e) {
|
||||
println(report(e));
|
||||
}
|
||||
}
|
||||
|
||||
public int writeInstr(Code_attribute attr, int pc)
|
||||
throws Code_attribute.InvalidIndex {
|
||||
String lP = "";
|
||||
int opcode = attr.getUnsignedByte(pc);
|
||||
int opcode2;
|
||||
String mnem;
|
||||
switch (opcode) {
|
||||
case opc_nonpriv:
|
||||
case opc_priv: {
|
||||
opcode2 = attr.getUnsignedByte(pc + 1);
|
||||
mnem = opcName((opcode << 8) + opcode2);
|
||||
if (mnem == null) {
|
||||
mnem = opcName(opcode) + " " + opcode2;
|
||||
}
|
||||
print(mnem);
|
||||
return 2;
|
||||
}
|
||||
case opc_wide: {
|
||||
opcode2 = attr.getUnsignedByte(pc + 1);
|
||||
mnem = opcName((opcode << 8) + opcode2);
|
||||
if (mnem == null) {
|
||||
print("bytecode " + opcode);
|
||||
return 1;
|
||||
}
|
||||
print(mnem + " " + attr.getUnsignedShort(pc + 2));
|
||||
if (opcode2 == opc_iinc) {
|
||||
print(", " + attr.getShort(pc + 4));
|
||||
return 6;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
mnem = opcName(opcode);
|
||||
if (mnem == null) {
|
||||
print("bytecode " + opcode);
|
||||
return 1;
|
||||
}
|
||||
if (opcode > opc_jsr_w) {
|
||||
print("bytecode " + opcode);
|
||||
return 1;
|
||||
}
|
||||
print(opcName(opcode));
|
||||
switch (opcode) {
|
||||
case opc_aload:
|
||||
case opc_astore:
|
||||
case opc_fload:
|
||||
case opc_fstore:
|
||||
case opc_iload:
|
||||
case opc_istore:
|
||||
case opc_lload:
|
||||
case opc_lstore:
|
||||
case opc_dload:
|
||||
case opc_dstore:
|
||||
case opc_ret:
|
||||
print("\t" + attr.getUnsignedByte(pc + 1));
|
||||
return 2;
|
||||
case opc_iinc:
|
||||
print("\t" + attr.getUnsignedByte(pc + 1) + ", " + attr.getByte(pc + 2));
|
||||
return 3;
|
||||
case opc_tableswitch:
|
||||
{
|
||||
int tb = align(pc + 1);
|
||||
int default_skip = attr.getInt(tb);
|
||||
int low = attr.getInt(tb + 4);
|
||||
int high = attr.getInt(tb + 8);
|
||||
int count = high - low;
|
||||
print("{ //" + low + " to " + high);
|
||||
for (int i = 0; i <= count; i++) {
|
||||
print("\n\t\t" + (i + low) + ": " + lP + (pc + attr.getInt(tb + 12 + 4 * i)) + ";");
|
||||
}
|
||||
print("\n\t\tdefault: " + lP + (default_skip + pc) + " }");
|
||||
return tb - pc + 16 + count * 4;
|
||||
}
|
||||
case opc_lookupswitch:
|
||||
{
|
||||
int tb = align(pc + 1);
|
||||
int default_skip = attr.getInt(tb);
|
||||
int npairs = attr.getInt(tb + 4);
|
||||
print("{ //" + npairs);
|
||||
for (int i = 1; i <= npairs; i++) {
|
||||
print("\n\t\t" + attr.getInt(tb + i * 8) + ": " + lP + (pc + attr.getInt(tb + 4 + i * 8)) + ";");
|
||||
}
|
||||
print("\n\t\tdefault: " + lP + (default_skip + pc) + " }");
|
||||
return tb - pc + (npairs + 1) * 8;
|
||||
}
|
||||
case opc_newarray:
|
||||
int type = attr.getUnsignedByte(pc + 1);
|
||||
switch (type) {
|
||||
case T_BOOLEAN:
|
||||
print(" boolean");
|
||||
break;
|
||||
case T_BYTE:
|
||||
print(" byte");
|
||||
break;
|
||||
case T_CHAR:
|
||||
print(" char");
|
||||
break;
|
||||
case T_SHORT:
|
||||
print(" short");
|
||||
break;
|
||||
case T_INT:
|
||||
print(" int");
|
||||
break;
|
||||
case T_LONG:
|
||||
print(" long");
|
||||
break;
|
||||
case T_FLOAT:
|
||||
print(" float");
|
||||
break;
|
||||
case T_DOUBLE:
|
||||
print(" double");
|
||||
break;
|
||||
case T_CLASS:
|
||||
print(" class");
|
||||
break;
|
||||
default:
|
||||
print(" BOGUS TYPE:" + type);
|
||||
}
|
||||
return 2;
|
||||
case opc_anewarray:
|
||||
{
|
||||
int index = attr.getUnsignedShort(pc + 1);
|
||||
print("\t#" + index + "; //");
|
||||
printConstant(index);
|
||||
return 3;
|
||||
}
|
||||
case opc_sipush:
|
||||
print("\t" + attr.getShort(pc + 1));
|
||||
return 3;
|
||||
case opc_bipush:
|
||||
print("\t" + attr.getByte(pc + 1));
|
||||
return 2;
|
||||
case opc_ldc:
|
||||
{
|
||||
int index = attr.getUnsignedByte(pc + 1);
|
||||
print("\t#" + index + "; //");
|
||||
printConstant(index);
|
||||
return 2;
|
||||
}
|
||||
case opc_ldc_w:
|
||||
case opc_ldc2_w:
|
||||
case opc_instanceof:
|
||||
case opc_checkcast:
|
||||
case opc_new:
|
||||
case opc_putstatic:
|
||||
case opc_getstatic:
|
||||
case opc_putfield:
|
||||
case opc_getfield:
|
||||
case opc_invokevirtual:
|
||||
case opc_invokespecial:
|
||||
case opc_invokestatic:
|
||||
{
|
||||
int index = attr.getUnsignedShort(pc + 1);
|
||||
print("\t#" + index + "; //");
|
||||
printConstant(index);
|
||||
return 3;
|
||||
}
|
||||
case opc_invokeinterface:
|
||||
{
|
||||
int index = attr.getUnsignedShort(pc + 1);
|
||||
int nargs = attr.getUnsignedByte(pc + 3);
|
||||
print("\t#" + index + ", " + nargs + "; //");
|
||||
printConstant(index);
|
||||
return 5;
|
||||
}
|
||||
case opc_multianewarray:
|
||||
{
|
||||
int index = attr.getUnsignedShort(pc + 1);
|
||||
int dimensions = attr.getUnsignedByte(pc + 3);
|
||||
print("\t#" + index + ", " + dimensions + "; //");
|
||||
printConstant(index);
|
||||
return 4;
|
||||
}
|
||||
case opc_jsr:
|
||||
case opc_goto:
|
||||
case opc_ifeq:
|
||||
case opc_ifge:
|
||||
case opc_ifgt:
|
||||
case opc_ifle:
|
||||
case opc_iflt:
|
||||
case opc_ifne:
|
||||
case opc_if_icmpeq:
|
||||
case opc_if_icmpne:
|
||||
case opc_if_icmpge:
|
||||
case opc_if_icmpgt:
|
||||
case opc_if_icmple:
|
||||
case opc_if_icmplt:
|
||||
case opc_if_acmpeq:
|
||||
case opc_if_acmpne:
|
||||
case opc_ifnull:
|
||||
case opc_ifnonnull:
|
||||
print("\t" + lP + (pc + attr.getShort(pc + 1)));
|
||||
return 3;
|
||||
case opc_jsr_w:
|
||||
case opc_goto_w:
|
||||
print("\t" + lP + (pc + attr.getInt(pc + 1)));
|
||||
return 5;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void writeExceptionTable(Code_attribute attr) {
|
||||
if (attr.exception_table_langth > 0) {
|
||||
println(" Exception table:");
|
||||
println(" from to target type");
|
||||
for (int i = 0; i < attr.exception_table.length; i++) {
|
||||
Code_attribute.Exception_data handler = attr.exception_table[i];
|
||||
printFixedWidthInt(handler.start_pc, 6);
|
||||
printFixedWidthInt(handler.end_pc, 6);
|
||||
printFixedWidthInt(handler.handler_pc, 6);
|
||||
print(" ");
|
||||
int catch_type = handler.catch_type;
|
||||
if (catch_type == 0) {
|
||||
println("any");
|
||||
} else {
|
||||
print("Class ");
|
||||
println(constantWriter.stringValue(catch_type));
|
||||
println("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void printConstant(int index) {
|
||||
constantWriter.write(index);
|
||||
}
|
||||
|
||||
private void printFixedWidthInt(int n, int width) {
|
||||
String s = String.valueOf(n);
|
||||
for (int i = s.length(); i < width; i++)
|
||||
print(" ");
|
||||
print(s);
|
||||
}
|
||||
|
||||
private static int align(int n) {
|
||||
return (n + 3) & ~3;
|
||||
}
|
||||
|
||||
private AttributeWriter attrWriter;
|
||||
private ClassWriter classWriter;
|
||||
private ConstantWriter constantWriter;
|
||||
}
|
@ -0,0 +1,352 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.ConstantPool;
|
||||
import com.sun.tools.classfile.ConstantPoolException;
|
||||
|
||||
import static com.sun.tools.classfile.ConstantPool.*;
|
||||
|
||||
/*
|
||||
* Write a constant pool entry.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class ConstantWriter extends BasicWriter {
|
||||
static ConstantWriter instance(Context context) {
|
||||
ConstantWriter instance = context.get(ConstantWriter.class);
|
||||
if (instance == null)
|
||||
instance = new ConstantWriter(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected ConstantWriter(Context context) {
|
||||
super(context);
|
||||
context.put(ConstantWriter.class, this);
|
||||
classWriter = ClassWriter.instance(context);
|
||||
options = Options.instance(context);
|
||||
}
|
||||
|
||||
void writeConstantPool() {
|
||||
ConstantPool.Visitor<Integer, Void> v = new ConstantPool.Visitor<Integer,Void>() {
|
||||
public Integer visitClass(CONSTANT_Class_info info, Void p) {
|
||||
println("#" + info.name_index + ";\t// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitDouble(CONSTANT_Double_info info, Void p) {
|
||||
println(stringValue(info) + ";");
|
||||
return 2;
|
||||
}
|
||||
|
||||
public Integer visitFieldref(CONSTANT_Fieldref_info info, Void p) {
|
||||
println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitFloat(CONSTANT_Float_info info, Void p) {
|
||||
println(stringValue(info) + ";");
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitInteger(CONSTANT_Integer_info info, Void p) {
|
||||
println(stringValue(info) + ";");
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
|
||||
println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitLong(CONSTANT_Long_info info, Void p) {
|
||||
println(stringValue(info) + ";");
|
||||
return 2;
|
||||
}
|
||||
|
||||
public Integer visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
|
||||
String tab = (options.compat ? "" : "\t"); // BUG 6622232 javap gets whitespace confused
|
||||
println("#" + info.name_index + ":#" + info.type_index + ";" + tab + "// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitMethodref(CONSTANT_Methodref_info info, Void p) {
|
||||
println("#" + info.class_index + ".#" + info.name_and_type_index + ";\t// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitString(CONSTANT_String_info info, Void p) {
|
||||
println("#" + info.string_index + ";\t// " + stringValue(info));
|
||||
return 1;
|
||||
}
|
||||
|
||||
public Integer visitUtf8(CONSTANT_Utf8_info info, Void p) {
|
||||
println(stringValue(info) + ";");
|
||||
return 1;
|
||||
}
|
||||
|
||||
};
|
||||
println(" Constant pool:");
|
||||
ConstantPool constant_pool = classWriter.getClassFile().constant_pool;
|
||||
int cpx = 1;
|
||||
while (cpx < constant_pool.size()) {
|
||||
try {
|
||||
CPInfo cpInfo = constant_pool.get(cpx);
|
||||
print("const #" + cpx + " = " + tagName(cpInfo.getTag()) + "\t");
|
||||
cpx += cpInfo.accept(v, null);
|
||||
} catch (ConstantPool.InvalidIndex ex) {
|
||||
print("const #" + cpx); // should not happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void write(int cpx) {
|
||||
ClassFile classFile = classWriter.getClassFile();
|
||||
if (cpx == 0) {
|
||||
print("#0");
|
||||
return;
|
||||
}
|
||||
|
||||
CPInfo cpInfo;
|
||||
try {
|
||||
cpInfo = classFile.constant_pool.get(cpx);
|
||||
} catch (ConstantPoolException e) {
|
||||
print("#" + cpx);
|
||||
return;
|
||||
}
|
||||
|
||||
int tag = cpInfo.getTag();
|
||||
switch (tag) {
|
||||
case CONSTANT_Methodref:
|
||||
case CONSTANT_InterfaceMethodref:
|
||||
case CONSTANT_Fieldref:
|
||||
// simplify references within this class
|
||||
CPRefInfo ref = (CPRefInfo) cpInfo;
|
||||
try {
|
||||
if (ref.class_index == classFile.this_class)
|
||||
cpInfo = classFile.constant_pool.get(ref.name_and_type_index);
|
||||
} catch (ConstantPool.InvalidIndex e) {
|
||||
// ignore, for now
|
||||
}
|
||||
}
|
||||
print(tagName(tag) + " " + stringValue(cpInfo));
|
||||
}
|
||||
|
||||
String tagName(int tag) {
|
||||
switch (tag) {
|
||||
case CONSTANT_Utf8:
|
||||
return "Asciz";
|
||||
case CONSTANT_Integer:
|
||||
return "int";
|
||||
case CONSTANT_Float:
|
||||
return "float";
|
||||
case CONSTANT_Long:
|
||||
return "long";
|
||||
case CONSTANT_Double:
|
||||
return "double";
|
||||
case CONSTANT_Class:
|
||||
return "class";
|
||||
case CONSTANT_String:
|
||||
return "String";
|
||||
case CONSTANT_Fieldref:
|
||||
return "Field";
|
||||
case CONSTANT_Methodref:
|
||||
return "Method";
|
||||
case CONSTANT_InterfaceMethodref:
|
||||
return "InterfaceMethod";
|
||||
case CONSTANT_NameAndType:
|
||||
return "NameAndType";
|
||||
default:
|
||||
return "unknown tag";
|
||||
}
|
||||
}
|
||||
|
||||
String stringValue(int constant_pool_index) {
|
||||
ClassFile classFile = classWriter.getClassFile();
|
||||
try {
|
||||
return stringValue(classFile.constant_pool.get(constant_pool_index));
|
||||
} catch (ConstantPool.InvalidIndex e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String stringValue(CPInfo cpInfo) {
|
||||
return stringValueVisitor.visit(cpInfo);
|
||||
}
|
||||
|
||||
StringValueVisitor stringValueVisitor = new StringValueVisitor();
|
||||
|
||||
private class StringValueVisitor implements ConstantPool.Visitor<String, Void> {
|
||||
public String visit(CPInfo info) {
|
||||
return info.accept(this, null);
|
||||
}
|
||||
|
||||
public String visitClass(CONSTANT_Class_info info, Void p) {
|
||||
return getCheckedName(info);
|
||||
}
|
||||
|
||||
String getCheckedName(CONSTANT_Class_info info) {
|
||||
try {
|
||||
return checkName(info.getName());
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String visitDouble(CONSTANT_Double_info info, Void p) {
|
||||
return info.value + "d";
|
||||
}
|
||||
|
||||
public String visitFieldref(CONSTANT_Fieldref_info info, Void p) {
|
||||
return visitRef(info, p);
|
||||
}
|
||||
|
||||
public String visitFloat(CONSTANT_Float_info info, Void p) {
|
||||
return info.value + "f";
|
||||
}
|
||||
|
||||
public String visitInteger(CONSTANT_Integer_info info, Void p) {
|
||||
return String.valueOf(info.value);
|
||||
}
|
||||
|
||||
public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, Void p) {
|
||||
return visitRef(info, p);
|
||||
}
|
||||
|
||||
public String visitLong(CONSTANT_Long_info info, Void p) {
|
||||
return info.value + "l";
|
||||
}
|
||||
|
||||
public String visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
|
||||
return getCheckedName(info) + ":" + getType(info);
|
||||
}
|
||||
|
||||
String getCheckedName(CONSTANT_NameAndType_info info) {
|
||||
try {
|
||||
return checkName(info.getName());
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
String getType(CONSTANT_NameAndType_info info) {
|
||||
try {
|
||||
return info.getType();
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String visitMethodref(CONSTANT_Methodref_info info, Void p) {
|
||||
return visitRef(info, p);
|
||||
}
|
||||
|
||||
public String visitString(CONSTANT_String_info info, Void p) {
|
||||
try {
|
||||
ClassFile classFile = classWriter.getClassFile();
|
||||
int string_index = info.string_index;
|
||||
return stringValue(classFile.constant_pool.getUTF8Info(string_index));
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String visitUtf8(CONSTANT_Utf8_info info, Void p) {
|
||||
String s = info.value;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
char c = s.charAt(i);
|
||||
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();
|
||||
}
|
||||
|
||||
String visitRef(CPRefInfo info, Void p) {
|
||||
String cn = getCheckedClassName(info);
|
||||
String nat;
|
||||
try {
|
||||
nat = stringValue(info.getNameAndTypeInfo());
|
||||
} catch (ConstantPoolException e) {
|
||||
nat = report(e);
|
||||
}
|
||||
return cn + "." + nat;
|
||||
}
|
||||
|
||||
String getCheckedClassName(CPRefInfo info) {
|
||||
try {
|
||||
return checkName(info.getClassName());
|
||||
} catch (ConstantPoolException e) {
|
||||
return report(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If name is a valid binary name, return it; otherwise quote it. */
|
||||
private static String checkName(String name) {
|
||||
if (name == null)
|
||||
return "null";
|
||||
|
||||
int len = name.length();
|
||||
if (len == 0)
|
||||
return "\"\"";
|
||||
|
||||
int cc = '/';
|
||||
int cp;
|
||||
for (int k = 0; k < len; k += Character.charCount(cp)) {
|
||||
cp = name.codePointAt(k);
|
||||
if ((cc == '/' && !Character.isJavaIdentifierStart(cp))
|
||||
|| (cp != '/' && !Character.isJavaIdentifierPart(cp))) {
|
||||
return "\"" + name + "\"";
|
||||
}
|
||||
cc = cp;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
private ClassWriter classWriter;
|
||||
private Options options;
|
||||
}
|
55
langtools/src/share/classes/com/sun/tools/javap/Context.java
Normal file
55
langtools/src/share/classes/com/sun/tools/javap/Context.java
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* Class from which to put/get shared resources.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Context {
|
||||
public Context() {
|
||||
map = new HashMap<Class<?>, Object>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(Class<T> key) {
|
||||
return (T) map.get(key);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T put(Class<T> key, T value) {
|
||||
return (T) map.put(key, value);
|
||||
}
|
||||
|
||||
Map<Class<?>, Object> map;
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2005-2006 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 com.sun.tools.javap; //javax.tools;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.OptionChecker;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.Tool;
|
||||
|
||||
/**
|
||||
* This class is intended to be put in javax.tools.
|
||||
*
|
||||
* @see DiagnosticListener
|
||||
* @see Diagnostic
|
||||
* @see JavaFileManager
|
||||
* @since 1.6
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public interface DisassemblerTool extends Tool, OptionChecker {
|
||||
|
||||
/**
|
||||
* Creates a future for a disassembly task with the given
|
||||
* components and arguments. The task might not have
|
||||
* completed as described in the DissemblerTask interface.
|
||||
*
|
||||
* <p>If a file manager is provided, it must be able to handle all
|
||||
* locations defined in {@link StandardLocation}.
|
||||
*
|
||||
* @param out a Writer for additional output from the compiler;
|
||||
* use {@code System.err} if {@code null}
|
||||
* @param fileManager a file manager; if {@code null} use the
|
||||
* compiler's standard filemanager
|
||||
* @param diagnosticListener a diagnostic listener; if {@code
|
||||
* null} use the compiler's default method for reporting
|
||||
* diagnostics
|
||||
* @param options compiler options, {@code null} means no options
|
||||
* @param classes class names (for annotation processing), {@code
|
||||
* null} means no class names
|
||||
* @param compilationUnits the compilation units to compile, {@code
|
||||
* null} means no compilation units
|
||||
* @return an object representing the compilation
|
||||
* @throws RuntimeException if an unrecoverable error
|
||||
* occurred in a user supplied component. The
|
||||
* {@linkplain Throwable#getCause() cause} will be the error in
|
||||
* user code.
|
||||
* @throws IllegalArgumentException if any of the given
|
||||
* compilation units are of other kind than
|
||||
* {@linkplain JavaFileObject.Kind#SOURCE source}
|
||||
*/
|
||||
DisassemblerTask getTask(Writer out,
|
||||
JavaFileManager fileManager,
|
||||
DiagnosticListener<? super JavaFileObject> diagnosticListener,
|
||||
Iterable<String> options,
|
||||
Iterable<String> classes);
|
||||
|
||||
/**
|
||||
* Gets a new instance of the standard file manager implementation
|
||||
* for this tool. The file manager will use the given diagnostic
|
||||
* listener for producing any non-fatal diagnostics. Fatal errors
|
||||
* will be signalled with the appropriate exceptions.
|
||||
*
|
||||
* <p>The standard file manager will be automatically reopened if
|
||||
* it is accessed after calls to {@code flush} or {@code close}.
|
||||
* The standard file manager must be usable with other tools.
|
||||
*
|
||||
* @param diagnosticListener a diagnostic listener for non-fatal
|
||||
* diagnostics; if {@code null} use the compiler's default method
|
||||
* for reporting diagnostics
|
||||
* @param locale the locale to apply when formatting diagnostics;
|
||||
* {@code null} means the {@linkplain Locale#getDefault() default locale}.
|
||||
* @param charset the character set used for decoding bytes; if
|
||||
* {@code null} use the platform default
|
||||
* @return the standard file manager
|
||||
*/
|
||||
StandardJavaFileManager getStandardFileManager(
|
||||
DiagnosticListener<? super JavaFileObject> diagnosticListener,
|
||||
Locale locale,
|
||||
Charset charset);
|
||||
|
||||
/**
|
||||
* Interface representing a future for a disassembly task. The
|
||||
* task has not yet started. To start the task, call
|
||||
* the {@linkplain #call call} method.
|
||||
*
|
||||
* <p>Before calling the call method, additional aspects of the
|
||||
* task can be configured, for example, by calling the
|
||||
* {@linkplain #setLocale setLocale} method.
|
||||
*/
|
||||
interface DisassemblerTask extends Callable<Boolean> {
|
||||
|
||||
/**
|
||||
* Set the locale to be applied when formatting diagnostics and
|
||||
* other localized data.
|
||||
*
|
||||
* @param locale the locale to apply; {@code null} means apply no
|
||||
* locale
|
||||
* @throws IllegalStateException if the task has started
|
||||
*/
|
||||
void setLocale(Locale locale);
|
||||
|
||||
/**
|
||||
* Performs this compilation task. The compilation may only
|
||||
* be performed once. Subsequent calls to this method throw
|
||||
* IllegalStateException.
|
||||
*
|
||||
* @return true if and only all the files compiled without errors;
|
||||
* false otherwise
|
||||
*
|
||||
* @throws RuntimeException if an unrecoverable error occurred
|
||||
* in a user-supplied component. The
|
||||
* {@linkplain Throwable#getCause() cause} will be the error
|
||||
* in user code.
|
||||
* @throws IllegalStateException if called more than once
|
||||
*/
|
||||
Boolean call();
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
/**
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class InternalError extends Error {
|
||||
InternalError(Throwable t, Object... args) {
|
||||
super("Internal error", t);
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
InternalError(Object... args) {
|
||||
super("Internal error");
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public final Object[] args;
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.JCDiagnostic;
|
||||
import com.sun.tools.javac.util.JavacFileManager;
|
||||
|
||||
/**
|
||||
* javap's implementation of JavaFileManager.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
class JavapFileManager extends JavacFileManager {
|
||||
private JavapFileManager(Context context, Charset charset) {
|
||||
super(context, true, charset);
|
||||
}
|
||||
|
||||
static JavapFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log, Options options) {
|
||||
Context javac_context = new Context();
|
||||
|
||||
if (dl != null) {
|
||||
// Workaround bug 6625520: javac handles missing entries on classpath badly
|
||||
// Ignore spurious errors for missing files
|
||||
DiagnosticListener<JavaFileObject> wrapper = new DiagnosticListener<JavaFileObject>() {
|
||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
if (diagnostic instanceof JCDiagnostic) {
|
||||
JCDiagnostic jcd = (JCDiagnostic) diagnostic;
|
||||
if (jcd.getCode().equals("compiler.err.error.reading.file")) {
|
||||
Object[] args = jcd.getArgs();
|
||||
if (args.length > 0 && args[0] != null && args[0].toString().length() > 0) {
|
||||
File f = new File(args[0].toString());
|
||||
if (!f.exists())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
dl.report(diagnostic);
|
||||
}
|
||||
};
|
||||
javac_context.put(DiagnosticListener.class, wrapper);
|
||||
}
|
||||
|
||||
javac_context.put(com.sun.tools.javac.util.Log.outKey, log);
|
||||
|
||||
return new JavapFileManager(javac_context, null);
|
||||
}
|
||||
|
||||
void setIgnoreSymbolFile(boolean b) {
|
||||
ignoreSymbolFile = b;
|
||||
}
|
||||
}
|
624
langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
Normal file
624
langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
Normal file
@ -0,0 +1,624 @@
|
||||
/*
|
||||
* Copyright 2007 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-15301 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 com.sun.tools.javap;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.classfile.*;
|
||||
|
||||
/**
|
||||
* "Main" class for javap, normally accessed from the command line
|
||||
* via Main, or from JSR199 via DisassemblerTool.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class JavapTask implements DisassemblerTool.DisassemblerTask {
|
||||
public class BadArgs extends Exception {
|
||||
static final long serialVersionUID = 8765093759964640721L;
|
||||
BadArgs(String key, Object... args) {
|
||||
super(JavapTask.this.getMessage(key, args));
|
||||
this.key = key;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
BadArgs showUsage(boolean b) {
|
||||
showUsage = b;
|
||||
return this;
|
||||
}
|
||||
|
||||
final String key;
|
||||
final Object[] args;
|
||||
boolean showUsage;
|
||||
}
|
||||
|
||||
static abstract class Option {
|
||||
Option(boolean hasArg, String... aliases) {
|
||||
this.hasArg = hasArg;
|
||||
this.aliases = aliases;
|
||||
}
|
||||
|
||||
boolean matches(String opt) {
|
||||
for (String a: aliases) {
|
||||
if (a.equals(opt))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean ignoreRest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
abstract void process(JavapTask task, String opt, String arg) throws BadArgs;
|
||||
|
||||
final boolean hasArg;
|
||||
final String[] aliases;
|
||||
}
|
||||
|
||||
static Option[] recognizedOptions = {
|
||||
|
||||
new Option(false, "-help", "--help", "-?") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.help = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-version") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.version = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-fullversion") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.fullVersion = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-v", "-verbose", "-all") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.verbose = true;
|
||||
task.options.showFlags = true;
|
||||
task.options.showAllAttrs = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-l") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showLineAndLocalVariableTables = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-public") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showAccess = AccessFlags.ACC_PUBLIC;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-protected") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showAccess = AccessFlags.ACC_PROTECTED;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-package") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showAccess = 0;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-p", "-private") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showAccess = AccessFlags.ACC_PRIVATE;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-c") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showDisassembled = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-s") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.showInternalSignatures = true;
|
||||
}
|
||||
},
|
||||
|
||||
// new Option(false, "-all") {
|
||||
// void process(JavapTask task, String opt, String arg) {
|
||||
// task.options.showAllAttrs = true;
|
||||
// }
|
||||
// },
|
||||
|
||||
new Option(false, "-h") {
|
||||
void process(JavapTask task, String opt, String arg) throws BadArgs {
|
||||
throw task.new BadArgs("err.h.not.supported");
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-verify", "-verify-verbose") {
|
||||
void process(JavapTask task, String opt, String arg) throws BadArgs {
|
||||
throw task.new BadArgs("err.verify.not.supported");
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-Xold") {
|
||||
void process(JavapTask task, String opt, String arg) throws BadArgs {
|
||||
// -Xold is only supported as first arg when invoked from
|
||||
// command line; this is handled in Main,main
|
||||
throw task.new BadArgs("err.Xold.not.supported.here");
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-Xnew") {
|
||||
void process(JavapTask task, String opt, String arg) throws BadArgs {
|
||||
// ignore: this _is_ the new version
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-XDcompat") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.compat = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-XDjsr277") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.jsr277 = true;
|
||||
}
|
||||
},
|
||||
|
||||
new Option(false, "-XDignore.symbol.file") {
|
||||
void process(JavapTask task, String opt, String arg) {
|
||||
task.options.ignoreSymbolFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
JavapTask() {
|
||||
context = new Context();
|
||||
options = Options.instance(context);
|
||||
}
|
||||
|
||||
JavapTask(Writer out,
|
||||
JavaFileManager fileManager,
|
||||
DiagnosticListener<? super JavaFileObject> diagnosticListener,
|
||||
Iterable<String> options,
|
||||
Iterable<String> classes) {
|
||||
this();
|
||||
this.log = getPrintWriterForWriter(out);
|
||||
this.fileManager = fileManager;
|
||||
this.diagnosticListener = diagnosticListener;
|
||||
|
||||
try {
|
||||
handleOptions(options, false);
|
||||
} catch (BadArgs e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
|
||||
this.classes = new ArrayList<String>();
|
||||
for (String classname: classes) {
|
||||
classname.getClass(); // null-check
|
||||
this.classes.add(classname);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLocale(Locale locale) {
|
||||
if (locale == null)
|
||||
locale = Locale.getDefault();
|
||||
task_locale = locale;
|
||||
}
|
||||
|
||||
public void setLog(PrintWriter log) {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public void setLog(OutputStream s) {
|
||||
setLog(getPrintWriterForStream(s));
|
||||
}
|
||||
|
||||
private static PrintWriter getPrintWriterForStream(OutputStream s) {
|
||||
return new PrintWriter(s, true);
|
||||
}
|
||||
|
||||
private static PrintWriter getPrintWriterForWriter(Writer w) {
|
||||
if (w == null)
|
||||
return getPrintWriterForStream(null);
|
||||
else if (w instanceof PrintWriter)
|
||||
return (PrintWriter) w;
|
||||
else
|
||||
return new PrintWriter(w, true);
|
||||
}
|
||||
|
||||
public void setDiagnosticListener(DiagnosticListener<? super JavaFileObject> dl) {
|
||||
diagnosticListener = dl;
|
||||
}
|
||||
|
||||
public void setDiagnosticListener(OutputStream s) {
|
||||
setDiagnosticListener(getDiagnosticListenerForStream(s));
|
||||
}
|
||||
|
||||
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForStream(OutputStream s) {
|
||||
return getDiagnosticListenerForWriter(getPrintWriterForStream(s));
|
||||
}
|
||||
|
||||
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForWriter(Writer w) {
|
||||
final PrintWriter pw = getPrintWriterForWriter(w);
|
||||
return new DiagnosticListener<JavaFileObject> () {
|
||||
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
||||
pw.print(getMessage("err.prefix"));
|
||||
pw.print(" ");
|
||||
}
|
||||
pw.println(diagnostic.getMessage(null));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int run(String[] args) {
|
||||
try {
|
||||
handleOptions(args);
|
||||
boolean ok = run();
|
||||
return ok ? 0 : 1;
|
||||
} catch (BadArgs e) {
|
||||
diagnosticListener.report(createDiagnostic(e.key, e.args));
|
||||
return 1;
|
||||
} catch (InternalError e) {
|
||||
Object[] e_args;
|
||||
if (e.getCause() == null)
|
||||
e_args = e.args;
|
||||
else {
|
||||
e_args = new Object[e.args.length + 1];
|
||||
e_args[0] = e.getCause();
|
||||
System.arraycopy(e.args, 0, e_args, 1, e.args.length);
|
||||
}
|
||||
diagnosticListener.report(createDiagnostic("err.internal.error", e_args));
|
||||
return 1;
|
||||
} finally {
|
||||
log.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleOptions(String[] args) throws BadArgs {
|
||||
handleOptions(Arrays.asList(args), true);
|
||||
}
|
||||
|
||||
private void handleOptions(Iterable<String> args, boolean allowClasses) throws BadArgs {
|
||||
if (log == null) {
|
||||
log = getPrintWriterForStream(System.out);
|
||||
if (diagnosticListener == null)
|
||||
diagnosticListener = getDiagnosticListenerForStream(System.err);
|
||||
} else {
|
||||
if (diagnosticListener == null)
|
||||
diagnosticListener = getDiagnosticListenerForWriter(log);
|
||||
}
|
||||
|
||||
|
||||
if (fileManager == null)
|
||||
fileManager = getDefaultFileManager(diagnosticListener, log);
|
||||
|
||||
Iterator<String> iter = args.iterator();
|
||||
if (!iter.hasNext())
|
||||
options.help = true;
|
||||
|
||||
while (iter.hasNext()) {
|
||||
String arg = iter.next();
|
||||
if (arg.startsWith("-"))
|
||||
handleOption(arg, iter);
|
||||
else if (allowClasses) {
|
||||
if (classes == null)
|
||||
classes = new ArrayList<String>();
|
||||
classes.add(arg);
|
||||
while (iter.hasNext())
|
||||
classes.add(iter.next());
|
||||
} else
|
||||
throw new BadArgs("err.unknown.option", arg).showUsage(true);
|
||||
}
|
||||
|
||||
if (options.ignoreSymbolFile && fileManager instanceof JavapFileManager)
|
||||
((JavapFileManager) fileManager).setIgnoreSymbolFile(true);
|
||||
|
||||
if ((classes == null || classes.size() == 0) &&
|
||||
!(options.help || options.version || options.fullVersion)) {
|
||||
throw new BadArgs("err.no.classes.specified");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleOption(String name, Iterator<String> rest) throws BadArgs {
|
||||
for (Option o: recognizedOptions) {
|
||||
if (o.matches(name)) {
|
||||
if (o.hasArg) {
|
||||
if (rest.hasNext())
|
||||
o.process(this, name, rest.next());
|
||||
else
|
||||
throw new BadArgs("err.missing.arg", name).showUsage(true);
|
||||
} else
|
||||
o.process(this, name, null);
|
||||
|
||||
if (o.ignoreRest()) {
|
||||
while (rest.hasNext())
|
||||
rest.next();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fileManager.handleOption(name, rest))
|
||||
return;
|
||||
|
||||
throw new BadArgs("err.unknown.option", name).showUsage(true);
|
||||
}
|
||||
|
||||
public Boolean call() {
|
||||
return run();
|
||||
}
|
||||
|
||||
public boolean run() {
|
||||
if (options.help)
|
||||
showHelp();
|
||||
|
||||
if (options.version || options.fullVersion)
|
||||
showVersion(options.fullVersion);
|
||||
|
||||
if (classes == null || classes.size() == 0)
|
||||
return true;
|
||||
|
||||
context.put(PrintWriter.class, log);
|
||||
ClassWriter classWriter = ClassWriter.instance(context);
|
||||
|
||||
boolean ok = true;
|
||||
|
||||
for (String className: classes) {
|
||||
JavaFileObject fo;
|
||||
try {
|
||||
if (className.endsWith(".class")) {
|
||||
if (fileManager instanceof StandardJavaFileManager) {
|
||||
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
|
||||
fo = sfm.getJavaFileObjects(className).iterator().next();
|
||||
} else {
|
||||
diagnosticListener.report(createDiagnostic("err.not.standard.file.manager", className));
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
fo = getClassFileObject(className);
|
||||
if (fo == null) {
|
||||
// see if it is an inner class, by replacing dots to $, starting from the right
|
||||
String cn = className;
|
||||
int lastDot;
|
||||
while (fo == null && (lastDot = cn.lastIndexOf(".")) != -1) {
|
||||
cn = cn.substring(0, lastDot) + "$" + cn.substring(lastDot + 1);
|
||||
fo = getClassFileObject(cn);
|
||||
}
|
||||
}
|
||||
if (fo == null) {
|
||||
diagnosticListener.report(createDiagnostic("err.class.not.found", className));
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Attribute.Factory attributeFactory = new Attribute.Factory();
|
||||
attributeFactory.setCompat(options.compat);
|
||||
attributeFactory.setJSR277(options.jsr277);
|
||||
ClassFile cf = ClassFile.read(fo.openInputStream(), attributeFactory);
|
||||
classWriter.write(cf);
|
||||
} catch (ConstantPoolException e) {
|
||||
diagnosticListener.report(createDiagnostic("err.bad.constant.pool", className, e.getLocalizedMessage()));
|
||||
ok = false;
|
||||
} catch (EOFException e) {
|
||||
diagnosticListener.report(createDiagnostic("err.end.of.file", className));
|
||||
ok = false;
|
||||
} catch (FileNotFoundException e) {
|
||||
diagnosticListener.report(createDiagnostic("err.file.not.found", e.getLocalizedMessage()));
|
||||
ok = false;
|
||||
} catch (IOException e) {
|
||||
//e.printStackTrace();
|
||||
Object msg = e.getLocalizedMessage();
|
||||
if (msg == null)
|
||||
msg = e;
|
||||
diagnosticListener.report(createDiagnostic("err.ioerror", className, msg));
|
||||
ok = false;
|
||||
} catch (Throwable t) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
t.printStackTrace(pw);
|
||||
pw.close();
|
||||
diagnosticListener.report(createDiagnostic("err.crash", t.toString(), sw.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
private JavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
|
||||
return JavapFileManager.create(dl, log, options);
|
||||
}
|
||||
|
||||
private JavaFileObject getClassFileObject(String className) throws IOException {
|
||||
JavaFileObject fo;
|
||||
fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
|
||||
if (fo == null)
|
||||
fo = fileManager.getJavaFileForInput(StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS);
|
||||
return fo;
|
||||
}
|
||||
|
||||
private void showHelp() {
|
||||
log.println(getMessage("main.usage", progname));
|
||||
for (Option o: recognizedOptions) {
|
||||
String name = o.aliases[0].substring(1); // there must always be at least one name
|
||||
if (name.startsWith("X") || name.equals("fullversion") || name.equals("h") || name.equals("verify"))
|
||||
continue;
|
||||
log.println(getMessage("main.opt." + name));
|
||||
}
|
||||
String[] fmOptions = { "-classpath", "-bootclasspath" };
|
||||
for (String o: fmOptions) {
|
||||
if (fileManager.isSupportedOption(o) == -1)
|
||||
continue;
|
||||
String name = o.substring(1);
|
||||
log.println(getMessage("main.opt." + name));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void showVersion(boolean full) {
|
||||
log.println(version(full ? "full" : "release"));
|
||||
}
|
||||
|
||||
private static final String versionRBName = "com.sun.tools.javap.resources.version";
|
||||
private static ResourceBundle versionRB;
|
||||
|
||||
private String version(String key) {
|
||||
// key=version: mm.nn.oo[-milestone]
|
||||
// key=full: mm.mm.oo[-milestone]-build
|
||||
if (versionRB == null) {
|
||||
try {
|
||||
versionRB = ResourceBundle.getBundle(versionRBName);
|
||||
} catch (MissingResourceException e) {
|
||||
return getMessage("version.resource.missing", System.getProperty("java.version"));
|
||||
}
|
||||
}
|
||||
try {
|
||||
return versionRB.getString(key);
|
||||
}
|
||||
catch (MissingResourceException e) {
|
||||
return getMessage("version.unknown", System.getProperty("java.version"));
|
||||
}
|
||||
}
|
||||
|
||||
private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) {
|
||||
return new Diagnostic<JavaFileObject>() {
|
||||
public Kind getKind() {
|
||||
return Diagnostic.Kind.ERROR;
|
||||
}
|
||||
|
||||
public JavaFileObject getSource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getPosition() {
|
||||
return Diagnostic.NOPOS;
|
||||
}
|
||||
|
||||
public long getStartPosition() {
|
||||
return Diagnostic.NOPOS;
|
||||
}
|
||||
|
||||
public long getEndPosition() {
|
||||
return Diagnostic.NOPOS;
|
||||
}
|
||||
|
||||
public long getLineNumber() {
|
||||
return Diagnostic.NOPOS;
|
||||
}
|
||||
|
||||
public long getColumnNumber() {
|
||||
return Diagnostic.NOPOS;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String getMessage(Locale locale) {
|
||||
return JavapTask.this.getMessage(locale, key, args);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private String getMessage(String key, Object... args) {
|
||||
return getMessage(task_locale, key, args);
|
||||
}
|
||||
|
||||
private String getMessage(Locale locale, String key, Object... args) {
|
||||
if (bundles == null) {
|
||||
// could make this a HashMap<Locale,SoftReference<ResourceBundle>>
|
||||
// and for efficiency, keep a hard reference to the bundle for the task
|
||||
// locale
|
||||
bundles = new HashMap<Locale, ResourceBundle>();
|
||||
}
|
||||
|
||||
if (locale == null)
|
||||
locale = Locale.getDefault();
|
||||
|
||||
ResourceBundle b = bundles.get(locale);
|
||||
if (b == null) {
|
||||
try {
|
||||
b = ResourceBundle.getBundle("com.sun.tools.javap.resources.javap", locale);
|
||||
bundles.put(locale, b);
|
||||
} catch (MissingResourceException e) {
|
||||
throw new InternalError("Cannot find javap resource bundle for locale " + locale);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return MessageFormat.format(b.getString(key), args);
|
||||
} catch (MissingResourceException e) {
|
||||
throw new InternalError(e, key);
|
||||
}
|
||||
}
|
||||
|
||||
Context context;
|
||||
JavaFileManager fileManager;
|
||||
PrintWriter log;
|
||||
DiagnosticListener<? super JavaFileObject> diagnosticListener;
|
||||
List<String> classes;
|
||||
Options options;
|
||||
//ResourceBundle bundle;
|
||||
Locale task_locale;
|
||||
Map<Locale, ResourceBundle> bundles;
|
||||
|
||||
private static final String progname = "javap";
|
||||
}
|
68
langtools/src/share/classes/com/sun/tools/javap/Main.java
Normal file
68
langtools/src/share/classes/com/sun/tools/javap/Main.java
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Main {
|
||||
/**
|
||||
* Main entry point for the launcher.
|
||||
* Note: This method calls System.exit.
|
||||
* @param args command line arguments
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
if (args.length >= 1 && args[0].equals("-Xold")) {
|
||||
String[] nArgs = new String[args.length - 1];
|
||||
System.arraycopy(args, 1, nArgs, 0, nArgs.length);
|
||||
sun.tools.javap.Main.main(args); // calls System.exit
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
JavapTask t = new JavapTask();
|
||||
int rc = t.run(args);
|
||||
System.exit(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point that does <i>not</i> call System.exit.
|
||||
* @param args command line arguments
|
||||
* @param out output stream
|
||||
* @return an exit code. 0 means success, non-zero means an error occurred.
|
||||
*/
|
||||
public static int run(String[] args, PrintWriter out) {
|
||||
JavapTask t = new JavapTask();
|
||||
t.setLog(out);
|
||||
return t.run(args);
|
||||
}
|
||||
}
|
84
langtools/src/share/classes/com/sun/tools/javap/Options.java
Normal file
84
langtools/src/share/classes/com/sun/tools/javap/Options.java
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2007 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 com.sun.tools.javap;
|
||||
|
||||
import com.sun.tools.classfile.AccessFlags;
|
||||
|
||||
/*
|
||||
* Provides access to javap's options, set via the command line
|
||||
* or JSR 199 API.
|
||||
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class Options {
|
||||
public static Options instance(Context context) {
|
||||
Options instance = context.get(Options.class);
|
||||
if (instance == null)
|
||||
instance = new Options(context);
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected Options(Context context) {
|
||||
context.put(Options.class, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks access of class, field or method.
|
||||
*/
|
||||
public boolean checkAccess(AccessFlags flags){
|
||||
|
||||
boolean isPublic = flags.is(AccessFlags.ACC_PUBLIC);
|
||||
boolean isProtected = flags.is(AccessFlags.ACC_PROTECTED);
|
||||
boolean isPrivate = flags.is(AccessFlags.ACC_PRIVATE);
|
||||
boolean isPackage = !(isPublic || isProtected || isPrivate);
|
||||
|
||||
if ((showAccess == AccessFlags.ACC_PUBLIC) && (isProtected || isPrivate || isPackage))
|
||||
return false;
|
||||
else if ((showAccess == AccessFlags.ACC_PROTECTED) && (isPrivate || isPackage))
|
||||
return false;
|
||||
else if ((showAccess == 0) && (isPrivate))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean help;
|
||||
public boolean verbose;
|
||||
public boolean version;
|
||||
public boolean fullVersion;
|
||||
public boolean showFlags;
|
||||
public boolean showLineAndLocalVariableTables;
|
||||
public int showAccess;
|
||||
public boolean showDisassembled;
|
||||
public boolean showInternalSignatures;
|
||||
public boolean showAllAttrs;
|
||||
|
||||
public boolean compat; // bug-for-bug compatibility mode with old javap
|
||||
public boolean jsr277;
|
||||
public boolean ignoreSymbolFile; // file manager should ignore ct.sym
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>javap: class file disassembler</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
Javap is a class file disassembler.
|
||||
</body>
|
||||
</html>
|
10
langtools/src/share/classes/com/sun/tools/javap/package.html
Normal file
10
langtools/src/share/classes/com/sun/tools/javap/package.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
</head>
|
||||
<body>
|
||||
Classes to dump class files in text format.
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,62 @@
|
||||
|
||||
err.prefix=Error:
|
||||
|
||||
err.bad.constant.pool=error while reading constant pool for {0}: {1}
|
||||
err.class.not.found=class not found: {0}
|
||||
err.crash=A serious internal error has occurred: {0}\nPlease file a bug report, and include the following information:\n{1}
|
||||
err.end.of.file=unexpected end of file while reading {0}
|
||||
err.file.not.found=file not found: {0}
|
||||
err.h.not.supported=-h is no longer available - use the 'javah' program
|
||||
err.internal.error=internal error: {0} {1} {2}
|
||||
err.ioerror=IO error reading {0}: {1}
|
||||
err.missing.arg=no value given for {0}
|
||||
err.no.classes.specified=no classes specified
|
||||
err.not.standard.file.manager=can only specify class files when using a standard file manager
|
||||
err.unknown.option=unknown option: {0}
|
||||
err.verify.not.supported=-verify not supported
|
||||
err.Xold.not.supported.here=-Xold must be given as the first option
|
||||
|
||||
main.usage=\
|
||||
Usage: {0} <options> <classes>\n\
|
||||
where possible options include:
|
||||
|
||||
|
||||
main.opt.help=\
|
||||
\ -help --help -? Print this usage message
|
||||
|
||||
main.opt.version=\
|
||||
\ -version Version information
|
||||
|
||||
main.opt.v=\
|
||||
\ -v -verbose Print additional information
|
||||
|
||||
main.opt.l=\
|
||||
\ -l Print line number and local variable tables
|
||||
|
||||
main.opt.public=\
|
||||
\ -public Show only public classes and members
|
||||
|
||||
main.opt.protected=\
|
||||
\ -protected Show protected/public classes and members
|
||||
|
||||
main.opt.package=\
|
||||
\ -package Show package/protected/public classes\n\
|
||||
\ and members (default)
|
||||
|
||||
main.opt.p=\
|
||||
\ -p -private Show all classes and members
|
||||
|
||||
main.opt.c=\
|
||||
\ -c Disassemble the code
|
||||
|
||||
main.opt.s=\
|
||||
\ -s Print internal type signatures
|
||||
|
||||
main.opt.classpath=\
|
||||
\ -classpath <path> Specify where to find user class files
|
||||
|
||||
main.opt.bootclasspath=\
|
||||
\ -bootclasspath <path> Override location of bootstrap class files
|
||||
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright 2007-2008 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.
|
||||
#
|
||||
|
||||
jdk=$(JDK_VERSION)
|
||||
full=$(FULL_VERSION)
|
||||
release=$(RELEASE)
|
@ -49,6 +49,12 @@ public class Main {
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
// unless first arg is -Xold, use new javap
|
||||
if (!(argv.length >= 1 && argv[0].equals("-Xold"))) {
|
||||
com.sun.tools.javap.Main.main(argv);
|
||||
return;
|
||||
}
|
||||
|
||||
entry(argv);
|
||||
if (errorOccurred) {
|
||||
System.exit(1);
|
||||
@ -178,6 +184,8 @@ public class Main {
|
||||
}
|
||||
} else if (arg.equals("-all")) {
|
||||
env.showallAttr = true;
|
||||
} else if (arg.equals("-Xold")) {
|
||||
// ignore: this is old javap
|
||||
} else {
|
||||
error("invalid flag: " + arg);
|
||||
usage();
|
||||
|
81
langtools/test/tools/javap/4870651/T4870651.java
Normal file
81
langtools/test/tools/javap/4870651/T4870651.java
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4870651
|
||||
* @summary javap should recognize generics, varargs, enum
|
||||
* @build T4870651 Test
|
||||
* @run main T4870651
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T4870651 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T4870651().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
verify("Test",
|
||||
"class Test<T, E extends java.lang.Exception & java.lang.Comparable<T>, U extends java.lang.Comparable>",
|
||||
"v1(java.lang.String...)");
|
||||
|
||||
verify("Test$Enum",
|
||||
"flags: ACC_FINAL, ACC_SUPER, ACC_ENUM",
|
||||
"flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM");
|
||||
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
String javap(String className) {
|
||||
String testClasses = System.getProperty("test.classes", ".");
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
String[] args = { "-classpath", testClasses, "-v", className };
|
||||
int rc = com.sun.tools.javap.Main.run(args, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
String output = sw.toString();
|
||||
System.out.println("class " + className);
|
||||
System.out.println(output);
|
||||
return output;
|
||||
}
|
||||
|
||||
void verify(String className, String... expects) {
|
||||
String output = javap(className);
|
||||
for (String expect: expects) {
|
||||
if (output.indexOf(expect)< 0)
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
76
langtools/test/tools/javap/4870651/Test.java
Normal file
76
langtools/test/tools/javap/4870651/Test.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
abstract class Test<T,E extends Exception & Comparable<T>,U extends Comparable> {
|
||||
T t;
|
||||
|
||||
Test(T t) { }
|
||||
<G> Test(G g, int i) { }
|
||||
|
||||
Test(String... args) { }
|
||||
Test(int i, Object[]... args) { }
|
||||
abstract void v1(String... args);
|
||||
abstract void v2(int i, String[]... args);
|
||||
|
||||
abstract void a1(int x);
|
||||
abstract void a2(int[] x);
|
||||
abstract void a3(T x);
|
||||
abstract void a4(T[] x);
|
||||
|
||||
abstract int r1();
|
||||
abstract int[] r2();
|
||||
abstract T r3();
|
||||
abstract T[] r4();
|
||||
|
||||
abstract <G> void ga1(int x);
|
||||
abstract <G> void ga2(int[] x);
|
||||
abstract <G> void ga3(G x);
|
||||
abstract <G> void ga4(G[] x);
|
||||
|
||||
abstract <G> int gr1();
|
||||
abstract <G> int[] gr2();
|
||||
abstract <G> G gr3();
|
||||
abstract <G> G[] gr4();
|
||||
|
||||
abstract <G extends Exception> void ge() throws G;
|
||||
|
||||
abstract void w(List<?> l);
|
||||
abstract void we(List<? extends T> l);
|
||||
abstract void ws(List<? super T> l);
|
||||
|
||||
abstract void t1() throws Error;
|
||||
abstract void t2() throws E;
|
||||
abstract void t3() throws E,Error;
|
||||
|
||||
abstract void i1(Test<T, E, Comparable> x);
|
||||
abstract void i3(Test<T, E, Comparable>.Inner<String> x);
|
||||
|
||||
class Inner<Q> { }
|
||||
class Inner2<Q> extends Inner<Q> { }
|
||||
|
||||
class Simple { }
|
||||
|
||||
enum Enum { e1, e2, e3 }
|
||||
}
|
147
langtools/test/tools/javap/ListTest.java
Normal file
147
langtools/test/tools/javap/ListTest.java
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.tools.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6439940
|
||||
* @summary Cleanup javap implementation
|
||||
* @run main/othervm ListTest
|
||||
*/
|
||||
public class ListTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ListTest().run();
|
||||
}
|
||||
|
||||
ListTest() {
|
||||
String v = System.getProperty("view.cmd");
|
||||
// v = "/opt/teamware/7.7/bin/filemerge -r";
|
||||
if (v != null) {
|
||||
viewResults = true;
|
||||
viewCmd = Arrays.asList(v.split(" +"));
|
||||
}
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
StandardLocation[] locs = new StandardLocation[] {
|
||||
StandardLocation.PLATFORM_CLASS_PATH,
|
||||
StandardLocation.CLASS_PATH,
|
||||
};
|
||||
|
||||
int count = 0;
|
||||
int pass = 0;
|
||||
for (StandardLocation loc: locs) {
|
||||
for (String testClassName: list(loc)) {
|
||||
count++;
|
||||
if (test(testClassName))
|
||||
pass++;
|
||||
}
|
||||
}
|
||||
|
||||
if (pass < count)
|
||||
throw new Error(pass + "/" + count + " test cases passed");
|
||||
}
|
||||
|
||||
Iterable<String> list(StandardLocation loc) throws IOException {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
StandardJavaFileManager sfm = compiler.getStandardFileManager(null, null, null);
|
||||
Set<JavaFileObject.Kind> kinds = Collections.singleton(JavaFileObject.Kind.CLASS);
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
for (JavaFileObject fo: sfm.list(loc, testPackage, kinds, true)) {
|
||||
//System.err.println(com.sun.tools.javac.util.Old199.getPath(fo));
|
||||
list.add(sfm.inferBinaryName(loc, fo));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
boolean test(String testClassName) throws Exception {
|
||||
String[] args = new String[options.size() + 1];
|
||||
options.toArray(args);
|
||||
args[args.length - 1] = testClassName;
|
||||
String oldOut = runOldJavap(args);
|
||||
String newOut = runNewJavap(args);
|
||||
boolean ok = oldOut.equals(newOut);
|
||||
System.err.println((ok ? "pass" : "FAIL") + ": " + testClassName);
|
||||
if (!ok && viewResults)
|
||||
view(oldOut, newOut);
|
||||
return ok;
|
||||
}
|
||||
|
||||
String runOldJavap(String[] args) {
|
||||
//System.err.println("OLD: " + Arrays.asList(args));
|
||||
PrintStream oldOut = System.out;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
System.setOut(new PrintStream(out));
|
||||
try {
|
||||
sun.tools.javap.Main.entry(args);
|
||||
} finally {
|
||||
System.setOut(oldOut);
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
String runNewJavap(String[] args) {
|
||||
String[] nArgs = new String[args.length + 2];
|
||||
nArgs[0] = "-XDcompat";
|
||||
nArgs[1] = "-XDignore.symbol.file";
|
||||
System.arraycopy(args, 0, nArgs, 2, args.length);
|
||||
//System.err.println("NEW: " + Arrays.asList(nArgs));
|
||||
StringWriter out = new StringWriter();
|
||||
com.sun.tools.javap.Main.run(nArgs, new PrintWriter(out, true));
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
File write(String text, String suffix) throws IOException {
|
||||
File f = File.createTempFile("ListTest", suffix);
|
||||
FileWriter out = new FileWriter(f);
|
||||
out.write(text);
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
void view(String oldOut, String newOut) throws Exception {
|
||||
File oldFile = write(oldOut, "old");
|
||||
File newFile = write(newOut, "new");
|
||||
List<String> cmd = new ArrayList<String>();
|
||||
cmd.addAll(viewCmd);
|
||||
cmd.add(oldFile.getPath());
|
||||
cmd.add(newFile.getPath());
|
||||
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
|
||||
p.getOutputStream().close();
|
||||
String line;
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
while ((line = in.readLine()) != null)
|
||||
System.err.println(line);
|
||||
in.close();
|
||||
p.waitFor();
|
||||
}
|
||||
|
||||
String testPackage = "java.lang";
|
||||
List<String> options = Arrays.asList("-v");
|
||||
boolean viewResults;
|
||||
List<String> viewCmd;
|
||||
}
|
143
langtools/test/tools/javap/OptionTest.java
Normal file
143
langtools/test/tools/javap/OptionTest.java
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2007 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6439940
|
||||
* @summary Cleanup javap implementation
|
||||
* @run main/othervm OptionTest
|
||||
*/
|
||||
public class OptionTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new OptionTest().run();
|
||||
}
|
||||
|
||||
OptionTest() {
|
||||
String v = System.getProperty("view.cmd");
|
||||
if (v != null) {
|
||||
viewResults = true;
|
||||
viewCmd = Arrays.asList(v.split(" +"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void run() throws Exception {
|
||||
int count = 0;
|
||||
int pass = 0;
|
||||
// try combinations of options and compare old javap against new javap
|
||||
for (int i = 0; i < (1<<8); i++) {
|
||||
List<String> options = new ArrayList<String>();
|
||||
if ((i & 0x01) != 0)
|
||||
options.add("-c");
|
||||
if ((i & 0x02) != 0)
|
||||
options.add("-l");
|
||||
if ((i & 0x04) != 0)
|
||||
options.add("-public");
|
||||
if ((i & 0x08) != 0)
|
||||
options.add("-protected");
|
||||
if ((i & 0x10) != 0)
|
||||
options.add("-package");
|
||||
if ((i & 0x20) != 0)
|
||||
options.add("-private");
|
||||
if ((i & 0x40) != 0)
|
||||
options.add("-s");
|
||||
if ((i & 0x80) != 0)
|
||||
options.add("-verbose");
|
||||
count++;
|
||||
if (test(options))
|
||||
pass++;
|
||||
}
|
||||
|
||||
if (pass < count)
|
||||
throw new Error(pass + "/" + count + " test cases passed");
|
||||
}
|
||||
|
||||
boolean test(List<String> options) throws Exception {
|
||||
String[] args = new String[options.size() + 1];
|
||||
options.toArray(args);
|
||||
args[args.length - 1] = testClassName;
|
||||
String oldOut = runOldJavap(args);
|
||||
String newOut = runNewJavap(args);
|
||||
boolean ok = oldOut.equals(newOut);
|
||||
System.err.println((ok ? "pass" : "FAIL") + ": " + options);
|
||||
if (!ok && viewResults)
|
||||
view(oldOut, newOut);
|
||||
return ok;
|
||||
}
|
||||
|
||||
String runOldJavap(String[] args) {
|
||||
//System.err.println("OLD: " + Arrays.asList(args));
|
||||
PrintStream oldOut = System.out;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
System.setOut(new PrintStream(out));
|
||||
try {
|
||||
sun.tools.javap.Main.entry(args);
|
||||
} finally {
|
||||
System.setOut(oldOut);
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
String runNewJavap(String[] args) {
|
||||
String[] nArgs = new String[args.length + 2];
|
||||
nArgs[0] = "-XDcompat";
|
||||
nArgs[1] = "-XDignore.symbol.file";
|
||||
System.arraycopy(args, 0, nArgs, 2, args.length);
|
||||
//System.err.println("NEW: " + Arrays.asList(nArgs));
|
||||
StringWriter out = new StringWriter();
|
||||
com.sun.tools.javap.Main.run(nArgs, new PrintWriter(out, true));
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
File write(String text, String suffix) throws IOException {
|
||||
File f = File.createTempFile("OptionTest", suffix);
|
||||
FileWriter out = new FileWriter(f);
|
||||
out.write(text);
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
void view(String oldOut, String newOut) throws Exception {
|
||||
File oldFile = write(oldOut, "old");
|
||||
File newFile = write(newOut, "new");
|
||||
List<String> cmd = new ArrayList<String>();
|
||||
cmd.addAll(viewCmd);
|
||||
cmd.add(oldFile.getPath());
|
||||
cmd.add(newFile.getPath());
|
||||
Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start();
|
||||
p.getOutputStream().close();
|
||||
String line;
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
while ((line = in.readLine()) != null)
|
||||
System.err.println(line);
|
||||
in.close();
|
||||
p.waitFor();
|
||||
}
|
||||
|
||||
String testClassName = "java.lang.SecurityManager";
|
||||
boolean viewResults;
|
||||
List<String> viewCmd;
|
||||
}
|
73
langtools/test/tools/javap/T4075403.java
Normal file
73
langtools/test/tools/javap/T4075403.java
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4075403
|
||||
* @summary Use javap to inquire about a specific inner class
|
||||
*/
|
||||
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T4075403 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T4075403().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
javap("Outer.Inner");
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Outer.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("class Outer { ");
|
||||
out.println(" class Inner { }");
|
||||
out.println("}");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
String javap(String className) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(new String[] { "-classpath", ".", className }, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
System.out.println(sw.toString());
|
||||
return sw.toString();
|
||||
}
|
||||
}
|
112
langtools/test/tools/javap/T4459541.java
Normal file
112
langtools/test/tools/javap/T4459541.java
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4459541
|
||||
* @summary "javap -l" shows line numbers as signed short; they should be unsigned.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T4459541 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T4459541().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
String output = javap(classFile);
|
||||
verify(output);
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
println("class Test {");
|
||||
println("void begin(int i) {");
|
||||
println("i++;");
|
||||
println("i++;");
|
||||
println("}");
|
||||
while (line < 32750)
|
||||
println("// " + line);
|
||||
println("void before_32767(int i) {");
|
||||
println("i++;");
|
||||
println("i++;");
|
||||
println("}");
|
||||
while (line < 32768-4)
|
||||
println("// " + line);
|
||||
println("void straddle_32768(int i) {");
|
||||
while (line < 32768+4)
|
||||
println("i++;");
|
||||
println("}");
|
||||
while (line < 65520)
|
||||
println("// " + line);
|
||||
println("void between_32768_and_65536(int i) {");
|
||||
println("i++;");
|
||||
println("i++;");
|
||||
println("}");
|
||||
while (line < 65536-4)
|
||||
println("// " + line);
|
||||
println("void straddle_65536(int i) {");
|
||||
while (line < 65536+4)
|
||||
println("i++;");
|
||||
println("}");
|
||||
println("}");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] { f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
String javap(File f) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(new String[] { "-l", f.getPath() }, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verify(String output) {
|
||||
System.out.println(output);
|
||||
if (output.indexOf("-") >= 0)
|
||||
throw new Error("- found in output");
|
||||
}
|
||||
|
||||
void println(String text) {
|
||||
out.println(text);
|
||||
line++;
|
||||
}
|
||||
|
||||
PrintWriter out;
|
||||
int line = 1;
|
||||
}
|
76
langtools/test/tools/javap/T4501660.java
Normal file
76
langtools/test/tools/javap/T4501660.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4501660
|
||||
* @summary change diagnostic of -help as 'print this help message and exit'
|
||||
* (actually, verify -help does not cause premature exit)
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class T4501660 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T4501660().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
String testClasses = System.getProperty("test.classes", ".");
|
||||
String output = javap("-classpath", testClasses, "-help", "T4501660");
|
||||
verify(output,
|
||||
"-public", "-protected", "-private", // check -help output is present
|
||||
"class T4501660" // check class output is present
|
||||
);
|
||||
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
String javap(String... args) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
//sun.tools.javap.Main.entry(args);
|
||||
int rc = com.sun.tools.javap.Main.run(args, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
System.out.println(sw);
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verify(String output, String... expects) {
|
||||
for (String expect: expects) {
|
||||
if (output.indexOf(expect)< 0)
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
70
langtools/test/tools/javap/T4876942.java
Normal file
70
langtools/test/tools/javap/T4876942.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4876942
|
||||
* @summary javap invoked without args does not print help screen
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class T4876942 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T4876942().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
String output = javap();
|
||||
verify(output, "-public", "-protected", "-private"); // check that some of the options are listed
|
||||
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
String javap(String... args) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
//sun.tools.javap.Main.entry(args);
|
||||
int rc = com.sun.tools.javap.Main.run(args, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verify(String output, String... expects) {
|
||||
for (String expect: expects) {
|
||||
if (output.indexOf(expect)< 0)
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
88
langtools/test/tools/javap/T4880663.java
Normal file
88
langtools/test/tools/javap/T4880663.java
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4880663
|
||||
* @summary javap could output whitespace between class name and opening brace
|
||||
*/
|
||||
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T4880663 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T4880663().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
verify(classFile, "class Test {");
|
||||
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("class Test { }");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
String javap(File classFile) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(new String[] { classFile.getPath() }, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
System.out.println(sw.toString());
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verify(File classFile, String... expects) {
|
||||
String output = javap(classFile);
|
||||
for (String expect: expects) {
|
||||
if (output.indexOf(expect)< 0)
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
94
langtools/test/tools/javap/T4975569.java
Normal file
94
langtools/test/tools/javap/T4975569.java
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4975569 6622215
|
||||
* @summary javap doesn't print new flag bits
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class T4975569
|
||||
{
|
||||
public static void main(String... args) {
|
||||
new T4975569().run();
|
||||
}
|
||||
|
||||
void run() {
|
||||
verify("T4975569$Anno", "flags: ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION");
|
||||
verify("T4975569$E", "flags: ACC_FINAL, ACC_SUPER, ACC_ENUM");
|
||||
verify("T4975569$S", "flags: ACC_BRIDGE, ACC_SYNTHETIC",
|
||||
"InnerClasses: \n static");
|
||||
verify("T4975569$V", "void m(java.lang.String...)",
|
||||
"flags: ACC_VARARGS");
|
||||
verify("T4975569$Prot", "InnerClasses: \n protected");
|
||||
//verify("T4975569$Priv", "InnerClasses");
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
void verify(String className, String... expects) {
|
||||
String output = javap(className);
|
||||
for (String expect: expects) {
|
||||
if (output.indexOf(expect)< 0)
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
|
||||
String javap(String className) {
|
||||
String testClasses = System.getProperty("test.classes", ".");
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
String[] args = { "-v", "-classpath", testClasses, className };
|
||||
int rc = com.sun.tools.javap.Main.run(args, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
String output = sw.toString();
|
||||
System.out.println("class " + className);
|
||||
System.out.println(output);
|
||||
return output;
|
||||
}
|
||||
|
||||
List x() { return null; };
|
||||
|
||||
class V { void m(String... args) { } }
|
||||
enum E { e; }
|
||||
@interface Anno { }
|
||||
static class S extends T4975569 {
|
||||
ArrayList x() { return null; }
|
||||
}
|
||||
|
||||
protected class Prot { }
|
||||
//private class Priv { int i; }
|
||||
}
|
||||
|
90
langtools/test/tools/javap/T6271787.java
Normal file
90
langtools/test/tools/javap/T6271787.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6271787
|
||||
* @summary javap dumps LocalVariableTypeTable attribute in hex, needs to print a table
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T6271787 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T6271787().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
|
||||
verify(classFile,
|
||||
"LocalVariableTypeTable:",
|
||||
"0 5 0 this LTest<TT;>;" // should consider decoding this in javap
|
||||
);
|
||||
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("class Test<T> { }");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
String javap(File f) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verify(File classFile, String... expects) {
|
||||
String output = javap(classFile);
|
||||
for (String expect: expects) {
|
||||
if (output.indexOf(expect)< 0)
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
0
langtools/test/tools/javap/T6305779.java
Normal file
0
langtools/test/tools/javap/T6305779.java
Normal file
95
langtools/test/tools/javap/T6474890.java
Normal file
95
langtools/test/tools/javap/T6474890.java
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6474890
|
||||
* @summary javap does not open .zip files in -classpath
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class T6474890 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T6474890().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
File classDir = new File("classes");
|
||||
classDir.mkdir();
|
||||
|
||||
String className = "Test";
|
||||
File javaFile = writeTestFile(className);
|
||||
compileTestFile(classDir, javaFile);
|
||||
|
||||
File zipFile = zip(classDir, new File(classDir + ".zip"));
|
||||
javap("-classpath", zipFile.getPath(), className);
|
||||
|
||||
File jarFile = zip(classDir, new File(classDir + ".jar"));
|
||||
javap("-classpath", zipFile.getPath(), className);
|
||||
}
|
||||
|
||||
File writeTestFile(String name) throws IOException {
|
||||
File f = new File(name + ".java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("class " + name + " { }");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
void compileTestFile(File classDir, File file) {
|
||||
int rc = com.sun.tools.javac.Main.compile(
|
||||
new String[] { "-d", classDir.getPath(), file.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
}
|
||||
|
||||
File zip(File dir, File zipFile) throws IOException {
|
||||
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
|
||||
for (File file: dir.listFiles()) {
|
||||
if (file.isFile()) {
|
||||
byte[] data = new byte[(int) file.length()];
|
||||
DataInputStream in = new DataInputStream(new FileInputStream(file));
|
||||
in.readFully(data);
|
||||
in.close();
|
||||
zipOut.putNextEntry(new ZipEntry(file.getName()));
|
||||
zipOut.write(data, 0, data.length);
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
}
|
||||
zipOut.close();
|
||||
return zipFile;
|
||||
}
|
||||
|
||||
String javap(String... args) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
//sun.tools.javap.Main.entry(args);
|
||||
int rc = com.sun.tools.javap.Main.run(args, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
return sw.toString();
|
||||
}
|
||||
}
|
52
langtools/test/tools/javap/T6587786.java
Normal file
52
langtools/test/tools/javap/T6587786.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6587786
|
||||
* @summary Javap throws error : "ERROR:Could not find <classname>" for JRE classes
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T6587786 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T6587786().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
javap("com.sun.javadoc.Doc", "com.sun.crypto.provider.ai");
|
||||
javap("com.sun.crypto.provider.ai", "com.sun.javadoc.ClassDoc");
|
||||
}
|
||||
|
||||
void javap(String... args) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
//sun.tools.javap.Main.entry(args);
|
||||
int rc = com.sun.tools.javap.Main.run(args, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
System.out.println(sw.toString());
|
||||
}
|
||||
}
|
77
langtools/test/tools/javap/T6622216.java
Normal file
77
langtools/test/tools/javap/T6622216.java
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6622216
|
||||
* @summary javap names some attributes incorrectly
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T6622216 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T6622216().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
String output = javap(classFile);
|
||||
verify(output);
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Outer.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("class Outer {");
|
||||
out.println(" class Inner { }");
|
||||
out.println("}");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] { f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
String javap(File f) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verify(String output) {
|
||||
System.out.println(output);
|
||||
if (output.indexOf("InnerClasses") == -1)
|
||||
throw new Error("InnerClasses not found in output");
|
||||
}
|
||||
}
|
97
langtools/test/tools/javap/T6622232.java
Normal file
97
langtools/test/tools/javap/T6622232.java
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6622232
|
||||
* @summary javap gets whitespace confused
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T6622232 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T6622232().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
String output = javap(classFile);
|
||||
|
||||
// these are all examples of bad whitespace from old javap
|
||||
verifyNot(output,
|
||||
"\\Q Constant value: int 3Deprecated: true\\E",
|
||||
"^Deprecated: true",
|
||||
"\\Q throws java.lang.Exception, java.lang.Error Deprecated: true\\E"
|
||||
);
|
||||
|
||||
if (errors > 0)
|
||||
throw new Error(errors + " found.");
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("class Test { ");
|
||||
out.println(" @Deprecated static final int f1 = 3;");
|
||||
out.println(" @Deprecated int f2;");
|
||||
out.println(" @Deprecated void m() throws Exception, Error { }");
|
||||
out.println("}");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] { "-g", f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
String javap(File f) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
System.out.println(sw.toString());
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verifyNot(String output, String... unexpects) {
|
||||
for (String unexpect: unexpects) {
|
||||
if (output.matches(unexpect))
|
||||
error(unexpect + " unexpectedly found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errors++;
|
||||
}
|
||||
|
||||
int errors;
|
||||
}
|
197
langtools/test/tools/javap/T6622260.java
Normal file
197
langtools/test/tools/javap/T6622260.java
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6622260
|
||||
* @summary javap prints negative bytes incorrectly in hex
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class T6622260 {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new T6622260().run();
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
File javaFile = writeTestFile();
|
||||
File classFile = compileTestFile(javaFile);
|
||||
modifyClassFile(classFile);
|
||||
String output = javap(classFile);
|
||||
verify(output);
|
||||
}
|
||||
|
||||
File writeTestFile() throws IOException {
|
||||
File f = new File("Test.java");
|
||||
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
|
||||
out.println("@Deprecated class Test { int f; void m() { } }");
|
||||
out.close();
|
||||
return f;
|
||||
}
|
||||
|
||||
File compileTestFile(File f) {
|
||||
int rc = com.sun.tools.javac.Main.compile(new String[] { f.getPath() });
|
||||
if (rc != 0)
|
||||
throw new Error("compilation failed. rc=" + rc);
|
||||
String path = f.getPath();
|
||||
return new File(path.substring(0, path.length() - 5) + ".class");
|
||||
}
|
||||
|
||||
void modifyClassFile(File f) throws IOException {
|
||||
String newAttributeName = "NonstandardAttribute";
|
||||
byte[] newAttributeData = { 0, 1, 2, 127, (byte)128, (byte)129, (byte)254, (byte)255 };
|
||||
|
||||
DataInputStream in = new DataInputStream(new FileInputStream(f));
|
||||
byte[] data = new byte[(int) f.length()];
|
||||
in.readFully(data);
|
||||
in.close();
|
||||
|
||||
in = new DataInputStream(new ByteArrayInputStream(data));
|
||||
in.skipBytes(4); // magic
|
||||
in.skipBytes(2); // minor
|
||||
in.skipBytes(2); // minor
|
||||
|
||||
int constantPoolPos = data.length - in.available();
|
||||
int constant_pool_count = skipConstantPool(in);
|
||||
|
||||
int flagsPos = data.length - in.available();
|
||||
in.skipBytes(2); // access_flags
|
||||
in.skipBytes(2); // this_class
|
||||
in.skipBytes(2); // super_class
|
||||
|
||||
int interfaces_count = in.readUnsignedShort();
|
||||
in.skipBytes(interfaces_count * 2);
|
||||
|
||||
int field_count = in.readUnsignedShort();
|
||||
for (int i = 0; i < field_count; i++) {
|
||||
in.skipBytes(6); // access_flags, name_index, descriptor_index
|
||||
skipAttributes(in);
|
||||
}
|
||||
|
||||
int method_count = in.readUnsignedShort();
|
||||
for (int i = 0; i < method_count; i++) {
|
||||
in.skipBytes(6); // access_flags, name_index, descriptor_index
|
||||
skipAttributes(in);
|
||||
}
|
||||
|
||||
int classAttributesPos = data.length - in.available();
|
||||
int attributes_count = in.readUnsignedShort();
|
||||
|
||||
f.renameTo(new File(f.getPath() + ".BAK"));
|
||||
DataOutputStream out = new DataOutputStream(new FileOutputStream(f));
|
||||
|
||||
// copy head
|
||||
out.write(data, 0, constantPoolPos);
|
||||
|
||||
// copy constant pool, adding in name of new attribute
|
||||
out.writeShort(constant_pool_count + 1);
|
||||
out.write(data, constantPoolPos + 2, flagsPos - constantPoolPos - 2);
|
||||
out.write(1); // CONSTANT_Utf8
|
||||
out.writeUTF(newAttributeName);
|
||||
|
||||
// copy flags, class, superclass, interfaces, fields and methods
|
||||
out.write(data, flagsPos, classAttributesPos - flagsPos);
|
||||
|
||||
// copy class attributes, adding in new attribute
|
||||
out.writeShort(attributes_count + 1);
|
||||
out.write(data, classAttributesPos + 2, data.length - classAttributesPos - 2);
|
||||
out.writeShort(constant_pool_count); // index of new attribute name
|
||||
out.writeInt(newAttributeData.length);
|
||||
out.write(newAttributeData);
|
||||
out.close();
|
||||
}
|
||||
|
||||
int skipConstantPool(DataInputStream in) throws IOException {
|
||||
int constant_pool_count = in.readUnsignedShort();
|
||||
for (int i = 1; i < constant_pool_count; i++) {
|
||||
int tag = in.readUnsignedByte();
|
||||
switch (tag) {
|
||||
case 1: // CONSTANT_Utf8
|
||||
int length = in.readUnsignedShort();
|
||||
in.skipBytes(length); // bytes
|
||||
break;
|
||||
|
||||
case 3: // CONSTANT_Integer
|
||||
case 4: // CONSTANT_Float
|
||||
in.skipBytes(4); // bytes
|
||||
break;
|
||||
|
||||
case 5: // CONSTANT_Long
|
||||
case 6: // CONSTANT_Double
|
||||
in.skipBytes(8); // high_bytes, low_bytes
|
||||
break;
|
||||
|
||||
case 7: // CONSTANT_Class
|
||||
in.skipBytes(2); // name_index
|
||||
break;
|
||||
|
||||
case 8: // CONSTANT_String
|
||||
in.skipBytes(2); // string_index
|
||||
break;
|
||||
|
||||
case 9: // CONSTANT_FieldRef
|
||||
case 10: // CONSTANT_Methodref
|
||||
case 11: // CONSTANT_InterfaceMethodref
|
||||
in.skipBytes(4); // class_index, name_and_type_index
|
||||
break;
|
||||
|
||||
case 12: // CONSTANT_NameAndType
|
||||
in.skipBytes(4); // name_index, descriptor_index
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("constant pool tag: " + tag);
|
||||
}
|
||||
}
|
||||
return constant_pool_count;
|
||||
}
|
||||
|
||||
int skipAttributes(DataInputStream in) throws IOException {
|
||||
int attributes_count = in.readUnsignedShort();
|
||||
for (int i = 0; i < attributes_count; i++) {
|
||||
in.skipBytes(2); // attribute_name_index;
|
||||
int length = in.readInt();
|
||||
in.skipBytes(length); // info
|
||||
}
|
||||
return attributes_count;
|
||||
}
|
||||
|
||||
String javap(File f) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter out = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(new String[] { "-v", f.getPath() }, out);
|
||||
if (rc != 0)
|
||||
throw new Error("javap failed. rc=" + rc);
|
||||
out.close();
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verify(String output) {
|
||||
System.out.println(output);
|
||||
if (output.indexOf("-") >= 0)
|
||||
throw new Error("- found in output");
|
||||
if (output.indexOf("FFFFFF") >= 0)
|
||||
throw new Error("FFFFFF found in output");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user