# HG changeset patch # User jjg # Date 1212524807 25200 # Node ID 7708bd6d800de3412ce328b8a905064f9d7877fb # Parent f7e64b33d5a429d381c8da4d9528b415cea927ed 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 " 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 diff -r f7e64b33d5a4 -r 7708bd6d800d make/build.properties --- a/make/build.properties Fri May 30 11:08:40 2008 +0100 +++ b/make/build.properties Tue Jun 03 13:26:47 2008 -0700 @@ -66,7 +66,7 @@ # 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 task for javac javadoc.jls3.url=http://java.sun.com/docs/books/jls/ @@ -120,6 +120,8 @@ tools/javah/ javap.includes = \ + com/sun/tools/classfile/ \ + com/sun/tools/javap/ \ sun/tools/javap/ javap.tests = \ diff -r f7e64b33d5a4 -r 7708bd6d800d make/build.xml --- a/make/build.xml Fri May 30 11:08:40 2008 +0100 +++ b/make/build.xml Tue Jun 03 13:26:47 2008 -0700 @@ -136,7 +136,7 @@ - + @@ -301,14 +301,15 @@ jarmainclass="sun.tools.javap.Main"/> - + - + + jarmainclass="sun.tools.javap.Main" + jarclasspath="javac.jar"/> @@ -480,7 +481,7 @@ destdir="@{gensrc.dir}" includes="@{includes}"/> - + diff -r f7e64b33d5a4 -r 7708bd6d800d make/netbeans/common/standard-ide-actions-no-javadoc.ent --- a/make/netbeans/common/standard-ide-actions-no-javadoc.ent Fri May 30 11:08:40 2008 +0100 +++ b/make/netbeans/common/standard-ide-actions-no-javadoc.ent Tue Jun 03 13:26:47 2008 -0700 @@ -157,5 +157,5 @@ - javadoc-nb + -javadoc-nb diff -r f7e64b33d5a4 -r 7708bd6d800d make/netbeans/common/standard-ide-actions.ent --- a/make/netbeans/common/standard-ide-actions.ent Fri May 30 11:08:40 2008 +0100 +++ b/make/netbeans/common/standard-ide-actions.ent Tue Jun 03 13:26:47 2008 -0700 @@ -157,5 +157,5 @@ - javadoc-nb + -javadoc-nb diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/AccessFlags.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/AccessFlags.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 getClassModifiers() { + int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags); + return getModifiers(f, classModifiers, Type.Class); + } + + public Set 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 getInnerClassModifiers() { + int f = ((flags & ACC_INTERFACE) != 0 ? flags & ~ACC_ABSTRACT : flags); + return getModifiers(f, innerClassModifiers, Type.InnerClass); + } + + public Set 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 getFieldModifiers() { + return getModifiers(fieldModifiers, Type.Field); + } + + public Set 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 getMethodModifiers() { + return getModifiers(methodModifiers, Type.Method); + } + + public Set getMethodFlags() { + return getFlags(methodFlags, Type.Method); + } + + private Set getModifiers(int[] modifierFlags, Type t) { + return getModifiers(flags, modifierFlags, t); + } + + private static Set getModifiers(int flags, int[] modifierFlags, Type t) { + Set s = new LinkedHashSet(); + for (int m: modifierFlags) { + if ((flags & m) != 0) + s.add(flagToModifier(m, t)); + } + return s; + } + + private Set getFlags(int[] expectedFlags, Type t) { + Set s = new LinkedHashSet(); + 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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Annotation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Annotation.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, P p); + + public interface Visitor { + 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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; + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/AnnotationDefault_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/AnnotationDefault_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitAnnotationDefault(this, data); + } + + public final Annotation.element_value default_value; +} + diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/** + *

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. + */ + +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 attrClass = standardAttributes.get(name); + if (attrClass != null) { + try { + Class[] constrArgTypes = {ClassReader.class, int.class, int.class}; + Constructor 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>(); + 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> 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 accept(Attribute.Visitor visitor, D data); + + public final int attribute_name_index; + public final int attribute_length; + + + public interface Visitor { + 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); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/AttributeException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/AttributeException.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/* + *

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. + */ +public class AttributeException extends Exception { + AttributeException() { } + + AttributeException(String msg) { + super(msg); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Attributes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Attributes.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/* + *

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. + */ +public class Attributes implements Iterable { + Attributes(ClassReader cr) throws IOException { + map = new HashMap(); + 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(); + 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 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 map; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/CharacterRangeTable_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/** + *

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. + */ +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 accept(Visitor 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; + }; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ClassFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ClassFile.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ClassReader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ClassReader.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/** + *

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. + */ +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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ClassTranslator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ClassTranslator.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +public class ClassTranslator + implements ConstantPool.Visitor> { + /** + * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 translations) { + CONSTANT_Utf8_info info2 = (CONSTANT_Utf8_info) translations.get(info); + if (info2 == null) { + info2 = info; + translations.put(info, info2); + } + return info; + } + +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ClassWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ClassWriter.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 { + 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 { + 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 { + + 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 { + 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; + } + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Code_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Code_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor 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; + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/CompilationID_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/CompilationID_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/** + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitCompilationID(this, data); + } + + public final int compilationID_index; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ConstantPool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ConstantPool.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor visitor, D data) { + return visitor.visitUtf8(this, data); + } + + public final String value; + } + + +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ConstantPoolException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ConstantPoolException.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/* + *

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. + */ +public class ConstantPoolException extends Exception { + ConstantPoolException(int index) { + this.index = index; + } + + public final int index; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ConstantValue_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ConstantValue_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitConstantValue(this, data); + } + + public final int constantvalue_index; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/DefaultAttribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/DefaultAttribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/* + *

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. + */ +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 accept(Visitor visitor, P p) { + return visitor.visitDefault(this, p); + } + + public final byte[] info; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Deprecated_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Deprecated_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitDeprecated(this, data); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Descriptor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Descriptor.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/DescriptorException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/DescriptorException.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/* + *

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. + */ +public class DescriptorException extends Exception { +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/EnclosingMethod_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/EnclosingMethod_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitEnclosingMethod(this, data); + } + + public final int class_index; + public final int method_index; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Exceptions_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Exceptions_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitExceptions(this, data); + } + + public final int number_of_exceptions; + public final int[] exception_index_table; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Field.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Field.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/* + *

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. + */ +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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/InnerClasses_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/InnerClasses_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor 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; + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/LineNumberTable_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor 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; + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/LocalVariableTable_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor 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; + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/LocalVariableTypeTable_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor 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; + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Method.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Method.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/* + *

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. + */ +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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ModuleExportTable_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ModuleExportTable_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, P p) { + return visitor.visitModuleExportTable(this, p); + } + + public final int[] export_type_table; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/ModuleMemberTable_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/ModuleMemberTable_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, P p) { + return visitor.visitModuleMemberTable(this, p); + } + + public final int[] package_member_table; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Module_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Module_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitModule(this, data); + } + + public final int module_name; + +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/OpCodes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/OpCodes.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 mnemocodes = new HashMap(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); + } + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/RuntimeAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/RuntimeAnnotations_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/RuntimeInvisibleAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/RuntimeInvisibleAnnotations_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, P p) { + return visitor.visitRuntimeInvisibleAnnotations(this, p); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/RuntimeInvisibleParameterAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/RuntimeInvisibleParameterAnnotations_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, P p) { + return visitor.visitRuntimeInvisibleParameterAnnotations(this, p); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/RuntimeParameterAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/RuntimeParameterAnnotations_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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; +} + diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/RuntimeVisibleAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/RuntimeVisibleAnnotations_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, P p) { + return visitor.visitRuntimeVisibleAnnotations(this, p); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/RuntimeVisibleParameterAnnotations_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/RuntimeVisibleParameterAnnotations_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, P p) { + return visitor.visitRuntimeVisibleParameterAnnotations(this, p); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Signature.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Signature.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 typeArgTypes = null; + if (sig.charAt(sigp) == '<') + typeArgTypes = parseTypeArgTypes(); + + if (sig.charAt(sigp) == '(') { + List argTypes = parseTypeSignatures(')'); + Type returnType = parseTypeSignature(); + List throwsTypes = null; + while (sigp < sig.length() && sig.charAt(sigp) == '^') { + sigp++; + if (throwsTypes == null) + throwsTypes = new ArrayList(); + 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 superinterfaces = new ArrayList(); + 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 parseTypeSignatures(char term) { + sigp++; + List types = new ArrayList(); + 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 argTypes = parseTypeSignatures('>'); + t = new Type.ClassType(sb.toString(), argTypes); + break; + + default: + sigp++; + sb.append(sigch); + break; + } + } + } + + private List parseTypeArgTypes() { + assert sig.charAt(sigp) == '<'; + sigp++; + List types = null; + types = new ArrayList(); + 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 interfaceBounds = null; + sigp = sep + 1; + if (sig.charAt(sigp) != ':') + classBound = parseTypeSignature(); + while (sig.charAt(sigp) == ':') { + sigp++; + if (interfaceBounds == null) + interfaceBounds = new ArrayList(); + 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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Signature_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Signature_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitSignature(this, data); + } + + public final int signature_index; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/SourceDebugExtension_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/SourceDebugExtension_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitSourceDebugExtension(this, data); + } + + public final byte[] debug_extension; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/SourceFile_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/SourceFile_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, P p) { + return visitor.visitSourceFile(this, p); + } + + public final int sourcefile_index; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/SourceID_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/SourceID_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/** + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitSourceID(this, data); + } + + public final int sourceID_index; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/StackMapTable_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/StackMapTable_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor 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 accept(Visitor visitor, D data); + + public final int frame_type; + + public static interface Visitor { + 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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 accept(Visitor 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; + + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/StackMap_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/StackMap_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/** + *

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. + */ +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 accept(Visitor 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); + } + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Synthetic_attribute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Synthetic_attribute.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 accept(Visitor visitor, D data) { + return visitor.visitSynthetic(this, data); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/Type.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/Type.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/* + *

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. + */ +public class Type { + protected Type() { } + + public boolean isObject() { + return false; + } + + protected static void append(StringBuilder sb, String prefix, List 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 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 argTypes, Type resultType) { + this(null, argTypes, resultType, null); + } + + public MethodType(List typeArgTypes, + List argTypes, + Type returnType, + List 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 typeArgTypes; + public final List argTypes; + public final Type returnType; + public final List throwsTypes; + } + + public static class ClassSigType extends Type { + public ClassSigType(List typeArgTypes, Type superclassType, List 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 typeArgTypes; + public final Type superclassType; + public final List superinterfaceTypes; + } + + public static class ClassType extends Type { + public ClassType(String name, List 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 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 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 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; + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/classfile/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/classfile/package.html Tue Jun 03 13:26:47 2008 -0700 @@ -0,0 +1,12 @@ + + + + + + + + A minimalist library to read and write class files into objects closely + based on the corresponding definitions in the Java Virtual Machine + Specification (JVMS). + + diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/AnnotationWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/AnnotationWriter.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 { + 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; + } + + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/AttributeWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +public class AttributeWriter extends BasicWriter + implements Attribute.Visitor +{ + 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 { + 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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/BasicWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/BasicWriter.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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; + } +} + diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/ClassWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/ClassWriter.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 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("")) { + print(getJavaName(classFile)); + print(getParameterTypes(d, flags)); + } else if (getName(m).equals("")) { + 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 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"); +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/CodeWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/CodeWriter.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/ConstantWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/ConstantWriter.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 v = new ConstantPool.Visitor() { + 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 { + 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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/Context.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/Context.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +public class Context { + public Context() { + map = new HashMap, Object>(); + } + + @SuppressWarnings("unchecked") + public T get(Class key) { + return (T) map.get(key); + } + + @SuppressWarnings("unchecked") + public T put(Class key, T value) { + return (T) map.put(key, value); + } + + Map, Object> map; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/DisassemblerTool.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/DisassemblerTool.java Tue Jun 03 13:26:47 2008 -0700 @@ -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 + * + *

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. + */ +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. + * + *

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 diagnosticListener, + Iterable options, + Iterable 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. + * + *

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 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. + * + *

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 { + + /** + * 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(); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/InternalError.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/InternalError.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; + +/** + *

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. + */ +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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/JavapFileManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/JavapFileManager.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +class JavapFileManager extends JavacFileManager { + private JavapFileManager(Context context, Charset charset) { + super(context, true, charset); + } + + static JavapFileManager create(final DiagnosticListener 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 wrapper = new DiagnosticListener() { + public void report(Diagnostic 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; + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/JavapTask.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/JavapTask.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 diagnosticListener, + Iterable options, + Iterable 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(); + 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 dl) { + diagnosticListener = dl; + } + + public void setDiagnosticListener(OutputStream s) { + setDiagnosticListener(getDiagnosticListenerForStream(s)); + } + + private DiagnosticListener getDiagnosticListenerForStream(OutputStream s) { + return getDiagnosticListenerForWriter(getPrintWriterForStream(s)); + } + + private DiagnosticListener getDiagnosticListenerForWriter(Writer w) { + final PrintWriter pw = getPrintWriterForWriter(w); + return new DiagnosticListener () { + public void report(Diagnostic 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 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 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(); + 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 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 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 createDiagnostic(final String key, final Object... args) { + return new Diagnostic() { + 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> + // and for efficiency, keep a hard reference to the bundle for the task + // locale + bundles = new HashMap(); + } + + 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 diagnosticListener; + List classes; + Options options; + //ResourceBundle bundle; + Locale task_locale; + Map bundles; + + private static final String progname = "javap"; +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/Main.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/Main.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + * + *

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. + */ +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 not 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); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/Options.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/Options.java Tue Jun 03 13:26:47 2008 -0700 @@ -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. + *

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. + */ +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 +} diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/overview.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/overview.html Tue Jun 03 13:26:47 2008 -0700 @@ -0,0 +1,10 @@ + + + + javap: class file disassembler + + + + Javap is a class file disassembler. + + diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/package.html Tue Jun 03 13:26:47 2008 -0700 @@ -0,0 +1,10 @@ + + + + + + + + Classes to dump class files in text format. + + diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/resources/javap.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/resources/javap.properties Tue Jun 03 13:26:47 2008 -0700 @@ -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} \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 Specify where to find user class files + +main.opt.bootclasspath=\ +\ -bootclasspath Override location of bootstrap class files + + + diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/com/sun/tools/javap/resources/version.properties-template --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/com/sun/tools/javap/resources/version.properties-template Tue Jun 03 13:26:47 2008 -0700 @@ -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) diff -r f7e64b33d5a4 -r 7708bd6d800d src/share/classes/sun/tools/javap/Main.java --- a/src/share/classes/sun/tools/javap/Main.java Fri May 30 11:08:40 2008 +0100 +++ b/src/share/classes/sun/tools/javap/Main.java Tue Jun 03 13:26:47 2008 -0700 @@ -49,6 +49,12 @@ } 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 @@ } } else if (arg.equals("-all")) { env.showallAttr = true; + } else if (arg.equals("-Xold")) { + // ignore: this is old javap } else { error("invalid flag: " + arg); usage(); diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/4870651/T4870651.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/4870651/T4870651.java Tue Jun 03 13:26:47 2008 -0700 @@ -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, 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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/4870651/Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/4870651/Test.java Tue Jun 03 13:26:47 2008 -0700 @@ -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,U extends Comparable> { + T t; + + Test(T t) { } + 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 void ga1(int x); + abstract void ga2(int[] x); + abstract void ga3(G x); + abstract void ga4(G[] x); + + abstract int gr1(); + abstract int[] gr2(); + abstract G gr3(); + abstract G[] gr4(); + + abstract void ge() throws G; + + abstract void w(List l); + abstract void we(List l); + abstract void ws(List l); + + abstract void t1() throws Error; + abstract void t2() throws E; + abstract void t3() throws E,Error; + + abstract void i1(Test x); + abstract void i3(Test.Inner x); + + class Inner { } + class Inner2 extends Inner { } + + class Simple { } + + enum Enum { e1, e2, e3 } +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/ListTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/ListTest.java Tue Jun 03 13:26:47 2008 -0700 @@ -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 list(StandardLocation loc) throws IOException { + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager sfm = compiler.getStandardFileManager(null, null, null); + Set kinds = Collections.singleton(JavaFileObject.Kind.CLASS); + + List list = new ArrayList(); + 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 cmd = new ArrayList(); + 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 options = Arrays.asList("-v"); + boolean viewResults; + List viewCmd; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/OptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/OptionTest.java Tue Jun 03 13:26:47 2008 -0700 @@ -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 options = new ArrayList(); + 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 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 cmd = new ArrayList(); + 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 viewCmd; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T4075403.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T4075403.java Tue Jun 03 13:26:47 2008 -0700 @@ -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(); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T4459541.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T4459541.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T4501660.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T4501660.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T4876942.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T4876942.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T4880663.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T4880663.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T4975569.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T4975569.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; } +} + diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T6271787.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T6271787.java Tue Jun 03 13:26:47 2008 -0700 @@ -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;" // 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 { }"); + 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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T6474890.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T6474890.java Tue Jun 03 13:26:47 2008 -0700 @@ -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(); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T6587786.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T6587786.java Tue Jun 03 13:26:47 2008 -0700 @@ -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 " 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()); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T6622216.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T6622216.java Tue Jun 03 13:26:47 2008 -0700 @@ -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"); + } +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T6622232.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T6622232.java Tue Jun 03 13:26:47 2008 -0700 @@ -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; +} diff -r f7e64b33d5a4 -r 7708bd6d800d test/tools/javap/T6622260.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javap/T6622260.java Tue Jun 03 13:26:47 2008 -0700 @@ -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"); + } +}