Clean up apache BCEL lib, no more stupid warnings

This commit is contained in:
Shevchik 2013-12-15 15:26:10 +04:00
parent 6548caeddb
commit 4f00ab70b1
275 changed files with 26436 additions and 24293 deletions

File diff suppressed because it is too large Load Diff

View File

@ -18,59 +18,69 @@ package org.apache.bcel;
/** /**
* Exception constants. * Exception constants.
* *
* @version $Id: ExceptionConstants.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ExceptionConstants.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author E. Haase * @author E. Haase
*/ */
public interface ExceptionConstants { public interface ExceptionConstants {
/** The mother of all exceptions /**
*/ * The mother of all exceptions
public static final Class<Throwable> THROWABLE = Throwable.class; */
/** Super class of any run-time exception public static final Class<Throwable> THROWABLE = Throwable.class;
*/ /**
public static final Class<RuntimeException> RUNTIME_EXCEPTION = RuntimeException.class; * Super class of any run-time exception
/** Super class of any linking exception (aka Linkage Error) */
*/ public static final Class<RuntimeException> RUNTIME_EXCEPTION = RuntimeException.class;
public static final Class<LinkageError> LINKING_EXCEPTION = LinkageError.class; /**
/** Linking Exceptions * Super class of any linking exception (aka Linkage Error)
*/ */
public static final Class<ClassCircularityError> CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; public static final Class<LinkageError> LINKING_EXCEPTION = LinkageError.class;
public static final Class<ClassFormatError> CLASS_FORMAT_ERROR = ClassFormatError.class; /**
public static final Class<ExceptionInInitializerError> EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; * Linking Exceptions
public static final Class<IncompatibleClassChangeError> INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; */
public static final Class<AbstractMethodError> ABSTRACT_METHOD_ERROR = AbstractMethodError.class; public static final Class<ClassCircularityError> CLASS_CIRCULARITY_ERROR = ClassCircularityError.class;
public static final Class<IllegalAccessError> ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; public static final Class<ClassFormatError> CLASS_FORMAT_ERROR = ClassFormatError.class;
public static final Class<InstantiationError> INSTANTIATION_ERROR = InstantiationError.class; public static final Class<ExceptionInInitializerError> EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class;
public static final Class<NoSuchFieldError> NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; public static final Class<IncompatibleClassChangeError> INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class;
public static final Class<NoSuchMethodError> NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; public static final Class<AbstractMethodError> ABSTRACT_METHOD_ERROR = AbstractMethodError.class;
public static final Class<NoClassDefFoundError> NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; public static final Class<IllegalAccessError> ILLEGAL_ACCESS_ERROR = IllegalAccessError.class;
public static final Class<UnsatisfiedLinkError> UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; public static final Class<InstantiationError> INSTANTIATION_ERROR = InstantiationError.class;
public static final Class<VerifyError> VERIFY_ERROR = VerifyError.class; public static final Class<NoSuchFieldError> NO_SUCH_FIELD_ERROR = NoSuchFieldError.class;
/* UnsupportedClassVersionError is new in JDK 1.2 */ public static final Class<NoSuchMethodError> NO_SUCH_METHOD_ERROR = NoSuchMethodError.class;
//public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; public static final Class<NoClassDefFoundError> NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class;
/** Run-Time Exceptions public static final Class<UnsatisfiedLinkError> UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class;
*/ public static final Class<VerifyError> VERIFY_ERROR = VerifyError.class;
public static final Class<NullPointerException> NULL_POINTER_EXCEPTION = NullPointerException.class; /* UnsupportedClassVersionError is new in JDK 1.2 */
public static final Class<ArrayIndexOutOfBoundsException> ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; // public static final Class UnsupportedClassVersionError =
public static final Class<ArithmeticException> ARITHMETIC_EXCEPTION = ArithmeticException.class; // UnsupportedClassVersionError.class;
public static final Class<NegativeArraySizeException> NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; /**
public static final Class<ClassCastException> CLASS_CAST_EXCEPTION = ClassCastException.class; * Run-Time Exceptions
public static final Class<IllegalMonitorStateException> ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; */
/** Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual public static final Class<NullPointerException> NULL_POINTER_EXCEPTION = NullPointerException.class;
* Machine Specification public static final Class<ArrayIndexOutOfBoundsException> ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class;
*/ public static final Class<ArithmeticException> ARITHMETIC_EXCEPTION = ArithmeticException.class;
public static final Class<?>[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { public static final Class<NegativeArraySizeException> NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class;
NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, public static final Class<ClassCastException> CLASS_CAST_EXCEPTION = ClassCastException.class;
EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR public static final Class<IllegalMonitorStateException> ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class;
}; // Chapter 5.1 /**
public static final Class<?>[] EXCS_FIELD_AND_METHOD_RESOLUTION = { * Pre-defined exception arrays according to chapters 5.1-5.4 of the Java
NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR * Virtual Machine Specification
}; // Chapter 5.2 */
public static final Class<?>[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) public static final Class<?>[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = {
public static final Class<?>[] EXCS_STRING_RESOLUTION = new Class[0]; NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR,
// Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR,
public static final Class<?>[] EXCS_ARRAY_EXCEPTION = { ILLEGAL_ACCESS_ERROR }; // Chapter 5.1
NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION public static final Class<?>[] EXCS_FIELD_AND_METHOD_RESOLUTION = {
}; NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR }; // Chapter
// 5.2
public static final Class<?>[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter
// 5.3
// (as
// below)
public static final Class<?>[] EXCS_STRING_RESOLUTION = new Class[0];
// Chapter 5.4 (no errors but the ones that _always_ could happen! How
// stupid.)
public static final Class<?>[] EXCS_ARRAY_EXCEPTION = {
NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION };
} }

View File

@ -23,239 +23,241 @@ import org.apache.bcel.util.SyntheticRepository;
/** /**
* The repository maintains informations about class interdependencies, e.g., * The repository maintains informations about class interdependencies, e.g.,
* whether a class is a sub-class of another. Delegates actual class loading * whether a class is a sub-class of another. Delegates actual class loading to
* to SyntheticRepository with current class path by default. * SyntheticRepository with current class path by default.
* *
* @see org.apache.bcel.util.Repository * @see org.apache.bcel.util.Repository
* @see org.apache.bcel.util.SyntheticRepository * @see org.apache.bcel.util.SyntheticRepository
* *
* @version $Id: Repository.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Repository.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class Repository { public abstract class Repository {
private static org.apache.bcel.util.Repository _repository = SyntheticRepository.getInstance(); private static org.apache.bcel.util.Repository _repository = SyntheticRepository
.getInstance();
/**
* @return currently used repository instance
*/
public static org.apache.bcel.util.Repository getRepository() {
return _repository;
}
/** @return currently used repository instance /**
*/ * Set repository instance to be used for class loading
public static org.apache.bcel.util.Repository getRepository() { */
return _repository; public static void setRepository(org.apache.bcel.util.Repository rep) {
} _repository = rep;
}
/**
* Lookup class somewhere found on your CLASSPATH, or whereever the
* repository instance looks for it.
*
* @return class object for given fully qualified class name
* @throws ClassNotFoundException
* if the class could not be found or parsed correctly
*/
public static JavaClass lookupClass(String class_name)
throws ClassNotFoundException {
return _repository.loadClass(class_name);
}
/** Set repository instance to be used for class loading /**
*/ * Try to find class source using the internal repository instance.
public static void setRepository( org.apache.bcel.util.Repository rep ) { *
_repository = rep; * @see Class
} * @return JavaClass object for given runtime class
* @throws ClassNotFoundException
* if the class could not be found or parsed correctly
*/
public static JavaClass lookupClass(Class<?> clazz)
throws ClassNotFoundException {
return _repository.loadClass(clazz);
}
/**
* @return class file object for given Java class by looking on the system
* class path; returns null if the class file can't be found
*/
public static ClassPath.ClassFile lookupClassFile(String class_name) {
try {
ClassPath path = _repository.getClassPath();
if (path == null) {
return null;
}
return path.getClassFile(class_name);
} catch (IOException e) {
return null;
}
}
/** Lookup class somewhere found on your CLASSPATH, or whereever the /**
* repository instance looks for it. * Clear the repository.
* */
* @return class object for given fully qualified class name public static void clearCache() {
* @throws ClassNotFoundException if the class could not be found or _repository.clear();
* parsed correctly }
*/
public static JavaClass lookupClass( String class_name ) throws ClassNotFoundException {
return _repository.loadClass(class_name);
}
/**
* Add clazz to repository if there isn't an equally named class already in
* there.
*
* @return old entry in repository
*/
public static JavaClass addClass(JavaClass clazz) {
JavaClass old = _repository.findClass(clazz.getClassName());
_repository.storeClass(clazz);
return old;
}
/** /**
* Try to find class source using the internal repository instance. * Remove class with given (fully qualified) name from repository.
* @see Class */
* @return JavaClass object for given runtime class public static void removeClass(String clazz) {
* @throws ClassNotFoundException if the class could not be found or _repository.removeClass(_repository.findClass(clazz));
* parsed correctly }
*/
public static JavaClass lookupClass( Class<?> clazz ) throws ClassNotFoundException {
return _repository.loadClass(clazz);
}
/**
* Remove given class from repository.
*/
public static void removeClass(JavaClass clazz) {
_repository.removeClass(clazz);
}
/** /**
* @return class file object for given Java class by looking on the * @return list of super classes of clazz in ascending order, i.e., Object
* system class path; returns null if the class file can't be * is always the last element
* found * @throws ClassNotFoundException
*/ * if any of the superclasses can't be found
public static ClassPath.ClassFile lookupClassFile( String class_name ) { */
try { public static JavaClass[] getSuperClasses(JavaClass clazz)
ClassPath path = _repository.getClassPath(); throws ClassNotFoundException {
if (path == null) { return clazz.getSuperClasses();
return null; }
}
return path.getClassFile(class_name);
} catch (IOException e) {
return null;
}
}
/**
* @return list of super classes of clazz in ascending order, i.e., Object
* is always the last element.
* @throws ClassNotFoundException
* if the named class or any of its superclasses can't be found
*/
public static JavaClass[] getSuperClasses(String class_name)
throws ClassNotFoundException {
JavaClass jc = lookupClass(class_name);
return getSuperClasses(jc);
}
/** Clear the repository. /**
*/ * @return all interfaces implemented by class and its super classes and the
public static void clearCache() { * interfaces that those interfaces extend, and so on. (Some people
_repository.clear(); * call this a transitive hull).
} * @throws ClassNotFoundException
* if any of the class's superclasses or superinterfaces can't
* be found
*/
public static JavaClass[] getInterfaces(JavaClass clazz)
throws ClassNotFoundException {
return clazz.getAllInterfaces();
}
/**
* @return all interfaces implemented by class and its super classes and the
* interfaces that extend those interfaces, and so on
* @throws ClassNotFoundException
* if the named class can't be found, or if any of its
* superclasses or superinterfaces can't be found
*/
public static JavaClass[] getInterfaces(String class_name)
throws ClassNotFoundException {
return getInterfaces(lookupClass(class_name));
}
/** /**
* Add clazz to repository if there isn't an equally named class already in there. * Equivalent to runtime "instanceof" operator.
* *
* @return old entry in repository * @return true, if clazz is an instance of super_class
*/ * @throws ClassNotFoundException
public static JavaClass addClass( JavaClass clazz ) { * if any superclasses or superinterfaces of clazz can't be
JavaClass old = _repository.findClass(clazz.getClassName()); * found
_repository.storeClass(clazz); */
return old; public static boolean instanceOf(JavaClass clazz, JavaClass super_class)
} throws ClassNotFoundException {
return clazz.instanceOf(super_class);
}
/**
* @return true, if clazz is an instance of super_class
* @throws ClassNotFoundException
* if either clazz or super_class can't be found
*/
public static boolean instanceOf(String clazz, String super_class)
throws ClassNotFoundException {
return instanceOf(lookupClass(clazz), lookupClass(super_class));
}
/** /**
* Remove class with given (fully qualified) name from repository. * @return true, if clazz is an instance of super_class
*/ * @throws ClassNotFoundException
public static void removeClass( String clazz ) { * if super_class can't be found
_repository.removeClass(_repository.findClass(clazz)); */
} public static boolean instanceOf(JavaClass clazz, String super_class)
throws ClassNotFoundException {
return instanceOf(clazz, lookupClass(super_class));
}
/**
* @return true, if clazz is an instance of super_class
* @throws ClassNotFoundException
* if clazz can't be found
*/
public static boolean instanceOf(String clazz, JavaClass super_class)
throws ClassNotFoundException {
return instanceOf(lookupClass(clazz), super_class);
}
/** /**
* Remove given class from repository. * @return true, if clazz is an implementation of interface inter
*/ * @throws ClassNotFoundException
public static void removeClass( JavaClass clazz ) { * if any superclasses or superinterfaces of clazz can't be
_repository.removeClass(clazz); * found
} */
public static boolean implementationOf(JavaClass clazz, JavaClass inter)
throws ClassNotFoundException {
return clazz.implementationOf(inter);
}
/**
* @return true, if clazz is an implementation of interface inter
* @throws ClassNotFoundException
* if clazz, inter, or any superclasses or superinterfaces of
* clazz can't be found
*/
public static boolean implementationOf(String clazz, String inter)
throws ClassNotFoundException {
return implementationOf(lookupClass(clazz), lookupClass(inter));
}
/** /**
* @return list of super classes of clazz in ascending order, i.e., * @return true, if clazz is an implementation of interface inter
* Object is always the last element * @throws ClassNotFoundException
* @throws ClassNotFoundException if any of the superclasses can't be found * if inter or any superclasses or superinterfaces of clazz
*/ * can't be found
public static JavaClass[] getSuperClasses( JavaClass clazz ) throws ClassNotFoundException { */
return clazz.getSuperClasses(); public static boolean implementationOf(JavaClass clazz, String inter)
} throws ClassNotFoundException {
return implementationOf(clazz, lookupClass(inter));
}
/**
/** * @return true, if clazz is an implementation of interface inter
* @return list of super classes of clazz in ascending order, i.e., * @throws ClassNotFoundException
* Object is always the last element. * if clazz or any superclasses or superinterfaces of clazz
* @throws ClassNotFoundException if the named class or any of its * can't be found
* superclasses can't be found */
*/ public static boolean implementationOf(String clazz, JavaClass inter)
public static JavaClass[] getSuperClasses( String class_name ) throws ClassNotFoundException { throws ClassNotFoundException {
JavaClass jc = lookupClass(class_name); return implementationOf(lookupClass(clazz), inter);
return getSuperClasses(jc); }
}
/**
* @return all interfaces implemented by class and its super
* classes and the interfaces that those interfaces extend, and so on.
* (Some people call this a transitive hull).
* @throws ClassNotFoundException if any of the class's
* superclasses or superinterfaces can't be found
*/
public static JavaClass[] getInterfaces( JavaClass clazz ) throws ClassNotFoundException {
return clazz.getAllInterfaces();
}
/**
* @return all interfaces implemented by class and its super
* classes and the interfaces that extend those interfaces, and so on
* @throws ClassNotFoundException if the named class can't be found,
* or if any of its superclasses or superinterfaces can't be found
*/
public static JavaClass[] getInterfaces( String class_name ) throws ClassNotFoundException {
return getInterfaces(lookupClass(class_name));
}
/**
* Equivalent to runtime "instanceof" operator.
* @return true, if clazz is an instance of super_class
* @throws ClassNotFoundException if any superclasses or superinterfaces
* of clazz can't be found
*/
public static boolean instanceOf( JavaClass clazz, JavaClass super_class )
throws ClassNotFoundException {
return clazz.instanceOf(super_class);
}
/**
* @return true, if clazz is an instance of super_class
* @throws ClassNotFoundException if either clazz or super_class
* can't be found
*/
public static boolean instanceOf( String clazz, String super_class )
throws ClassNotFoundException {
return instanceOf(lookupClass(clazz), lookupClass(super_class));
}
/**
* @return true, if clazz is an instance of super_class
* @throws ClassNotFoundException if super_class can't be found
*/
public static boolean instanceOf( JavaClass clazz, String super_class )
throws ClassNotFoundException {
return instanceOf(clazz, lookupClass(super_class));
}
/**
* @return true, if clazz is an instance of super_class
* @throws ClassNotFoundException if clazz can't be found
*/
public static boolean instanceOf( String clazz, JavaClass super_class )
throws ClassNotFoundException {
return instanceOf(lookupClass(clazz), super_class);
}
/**
* @return true, if clazz is an implementation of interface inter
* @throws ClassNotFoundException if any superclasses or superinterfaces
* of clazz can't be found
*/
public static boolean implementationOf( JavaClass clazz, JavaClass inter )
throws ClassNotFoundException {
return clazz.implementationOf(inter);
}
/**
* @return true, if clazz is an implementation of interface inter
* @throws ClassNotFoundException if clazz, inter, or any superclasses
* or superinterfaces of clazz can't be found
*/
public static boolean implementationOf( String clazz, String inter )
throws ClassNotFoundException {
return implementationOf(lookupClass(clazz), lookupClass(inter));
}
/**
* @return true, if clazz is an implementation of interface inter
* @throws ClassNotFoundException if inter or any superclasses
* or superinterfaces of clazz can't be found
*/
public static boolean implementationOf( JavaClass clazz, String inter )
throws ClassNotFoundException {
return implementationOf(clazz, lookupClass(inter));
}
/**
* @return true, if clazz is an implementation of interface inter
* @throws ClassNotFoundException if clazz or any superclasses or
* superinterfaces of clazz can't be found
*/
public static boolean implementationOf( String clazz, JavaClass inter )
throws ClassNotFoundException {
return implementationOf(lookupClass(clazz), inter);
}
} }

View File

@ -19,220 +19,194 @@ package org.apache.bcel.classfile;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* Super class for all objects that have modifiers like private, final, ... * Super class for all objects that have modifiers like private, final, ... I.e.
* I.e. classes, fields, and methods. * classes, fields, and methods.
* *
* @version $Id: AccessFlags.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: AccessFlags.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class AccessFlags implements java.io.Serializable { public abstract class AccessFlags implements java.io.Serializable {
protected int access_flags; /**
*
*/
private static final long serialVersionUID = 1L;
protected int access_flags;
public AccessFlags() {
}
/**
* @param a
* inital access flags
*/
public AccessFlags(int a) {
access_flags = a;
}
/**
* @return Access flags of the object aka. "modifiers".
*/
public final int getAccessFlags() {
return access_flags;
}
/**
* @return Access flags of the object aka. "modifiers".
*/
public final int getModifiers() {
return access_flags;
}
/**
* Set access flags aka "modifiers".
*
* @param access_flags
* Access flags of the object.
*/
public final void setAccessFlags(int access_flags) {
this.access_flags = access_flags;
}
/**
* Set access flags aka "modifiers".
*
* @param access_flags
* Access flags of the object.
*/
public final void setModifiers(int access_flags) {
setAccessFlags(access_flags);
}
private final void setFlag(int flag, boolean set) {
if ((access_flags & flag) != 0) { // Flag is set already
if (!set) {
access_flags ^= flag;
}
} else { // Flag not set
if (set) {
access_flags |= flag;
}
}
}
public final void isPublic(boolean flag) {
setFlag(Constants.ACC_PUBLIC, flag);
}
public final boolean isPublic() {
return (access_flags & Constants.ACC_PUBLIC) != 0;
}
public final void isPrivate(boolean flag) {
setFlag(Constants.ACC_PRIVATE, flag);
}
public final boolean isPrivate() {
return (access_flags & Constants.ACC_PRIVATE) != 0;
}
public final void isProtected(boolean flag) {
setFlag(Constants.ACC_PROTECTED, flag);
}
public final boolean isProtected() {
return (access_flags & Constants.ACC_PROTECTED) != 0;
}
public final void isStatic(boolean flag) {
setFlag(Constants.ACC_STATIC, flag);
}
public final boolean isStatic() {
return (access_flags & Constants.ACC_STATIC) != 0;
}
public final void isFinal(boolean flag) {
setFlag(Constants.ACC_FINAL, flag);
}
public final boolean isFinal() {
return (access_flags & Constants.ACC_FINAL) != 0;
}
public final void isSynchronized(boolean flag) {
setFlag(Constants.ACC_SYNCHRONIZED, flag);
}
public final boolean isSynchronized() {
return (access_flags & Constants.ACC_SYNCHRONIZED) != 0;
}
public final void isVolatile(boolean flag) {
setFlag(Constants.ACC_VOLATILE, flag);
}
public final boolean isVolatile() {
return (access_flags & Constants.ACC_VOLATILE) != 0;
}
public final void isTransient(boolean flag) {
setFlag(Constants.ACC_TRANSIENT, flag);
}
public final boolean isTransient() {
return (access_flags & Constants.ACC_TRANSIENT) != 0;
}
public final void isNative(boolean flag) {
setFlag(Constants.ACC_NATIVE, flag);
}
public final boolean isNative() {
return (access_flags & Constants.ACC_NATIVE) != 0;
}
public final void isInterface(boolean flag) {
setFlag(Constants.ACC_INTERFACE, flag);
}
public final boolean isInterface() {
return (access_flags & Constants.ACC_INTERFACE) != 0;
}
public final void isAbstract(boolean flag) {
setFlag(Constants.ACC_ABSTRACT, flag);
}
public final boolean isAbstract() {
return (access_flags & Constants.ACC_ABSTRACT) != 0;
}
public final void isStrictfp(boolean flag) {
setFlag(Constants.ACC_STRICT, flag);
}
public final boolean isStrictfp() {
return (access_flags & Constants.ACC_STRICT) != 0;
}
public final void isSynthetic(boolean flag) {
setFlag(Constants.ACC_SYNTHETIC, flag);
}
public final boolean isSynthetic() {
return (access_flags & Constants.ACC_SYNTHETIC) != 0;
}
public AccessFlags() { public final void isAnnotation(boolean flag) {
} setFlag(Constants.ACC_ANNOTATION, flag);
}
public final boolean isAnnotation() {
return (access_flags & Constants.ACC_ANNOTATION) != 0;
}
/** public final void isEnum(boolean flag) {
* @param a inital access flags setFlag(Constants.ACC_ENUM, flag);
*/ }
public AccessFlags(int a) {
access_flags = a;
}
public final boolean isEnum() {
/** return (access_flags & Constants.ACC_ENUM) != 0;
* @return Access flags of the object aka. "modifiers". }
*/
public final int getAccessFlags() {
return access_flags;
}
/**
* @return Access flags of the object aka. "modifiers".
*/
public final int getModifiers() {
return access_flags;
}
/** Set access flags aka "modifiers".
* @param access_flags Access flags of the object.
*/
public final void setAccessFlags( int access_flags ) {
this.access_flags = access_flags;
}
/** Set access flags aka "modifiers".
* @param access_flags Access flags of the object.
*/
public final void setModifiers( int access_flags ) {
setAccessFlags(access_flags);
}
private final void setFlag( int flag, boolean set ) {
if ((access_flags & flag) != 0) { // Flag is set already
if (!set) {
access_flags ^= flag;
}
} else { // Flag not set
if (set) {
access_flags |= flag;
}
}
}
public final void isPublic( boolean flag ) {
setFlag(Constants.ACC_PUBLIC, flag);
}
public final boolean isPublic() {
return (access_flags & Constants.ACC_PUBLIC) != 0;
}
public final void isPrivate( boolean flag ) {
setFlag(Constants.ACC_PRIVATE, flag);
}
public final boolean isPrivate() {
return (access_flags & Constants.ACC_PRIVATE) != 0;
}
public final void isProtected( boolean flag ) {
setFlag(Constants.ACC_PROTECTED, flag);
}
public final boolean isProtected() {
return (access_flags & Constants.ACC_PROTECTED) != 0;
}
public final void isStatic( boolean flag ) {
setFlag(Constants.ACC_STATIC, flag);
}
public final boolean isStatic() {
return (access_flags & Constants.ACC_STATIC) != 0;
}
public final void isFinal( boolean flag ) {
setFlag(Constants.ACC_FINAL, flag);
}
public final boolean isFinal() {
return (access_flags & Constants.ACC_FINAL) != 0;
}
public final void isSynchronized( boolean flag ) {
setFlag(Constants.ACC_SYNCHRONIZED, flag);
}
public final boolean isSynchronized() {
return (access_flags & Constants.ACC_SYNCHRONIZED) != 0;
}
public final void isVolatile( boolean flag ) {
setFlag(Constants.ACC_VOLATILE, flag);
}
public final boolean isVolatile() {
return (access_flags & Constants.ACC_VOLATILE) != 0;
}
public final void isTransient( boolean flag ) {
setFlag(Constants.ACC_TRANSIENT, flag);
}
public final boolean isTransient() {
return (access_flags & Constants.ACC_TRANSIENT) != 0;
}
public final void isNative( boolean flag ) {
setFlag(Constants.ACC_NATIVE, flag);
}
public final boolean isNative() {
return (access_flags & Constants.ACC_NATIVE) != 0;
}
public final void isInterface( boolean flag ) {
setFlag(Constants.ACC_INTERFACE, flag);
}
public final boolean isInterface() {
return (access_flags & Constants.ACC_INTERFACE) != 0;
}
public final void isAbstract( boolean flag ) {
setFlag(Constants.ACC_ABSTRACT, flag);
}
public final boolean isAbstract() {
return (access_flags & Constants.ACC_ABSTRACT) != 0;
}
public final void isStrictfp( boolean flag ) {
setFlag(Constants.ACC_STRICT, flag);
}
public final boolean isStrictfp() {
return (access_flags & Constants.ACC_STRICT) != 0;
}
public final void isSynthetic( boolean flag ) {
setFlag(Constants.ACC_SYNTHETIC, flag);
}
public final boolean isSynthetic() {
return (access_flags & Constants.ACC_SYNTHETIC) != 0;
}
public final void isAnnotation( boolean flag ) {
setFlag(Constants.ACC_ANNOTATION, flag);
}
public final boolean isAnnotation() {
return (access_flags & Constants.ACC_ANNOTATION) != 0;
}
public final void isEnum( boolean flag ) {
setFlag(Constants.ACC_ENUM, flag);
}
public final boolean isEnum() {
return (access_flags & Constants.ACC_ENUM) != 0;
}
} }

View File

@ -22,257 +22,276 @@ import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* Abstract super class for <em>Attribute</em> objects. Currently the * Abstract super class for <em>Attribute</em> objects. Currently the
* <em>ConstantValue</em>, <em>SourceFile</em>, <em>Code</em>, * <em>ConstantValue</em>, <em>SourceFile</em>, <em>Code</em>,
* <em>Exceptiontable</em>, <em>LineNumberTable</em>, * <em>Exceptiontable</em>, <em>LineNumberTable</em>,
* <em>LocalVariableTable</em>, <em>InnerClasses</em> and * <em>LocalVariableTable</em>, <em>InnerClasses</em> and <em>Synthetic</em>
* <em>Synthetic</em> attributes are supported. The * attributes are supported. The <em>Unknown</em> attribute stands for
* <em>Unknown</em> attribute stands for non-standard-attributes. * non-standard-attributes.
* *
* @version $Id: Attribute.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Attribute.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see ConstantValue * @see ConstantValue
* @see SourceFile * @see SourceFile
* @see Code * @see Code
* @see Unknown * @see Unknown
* @see ExceptionTable * @see ExceptionTable
* @see LineNumberTable * @see LineNumberTable
* @see LocalVariableTable * @see LocalVariableTable
* @see InnerClasses * @see InnerClasses
* @see Synthetic * @see Synthetic
* @see Deprecated * @see Deprecated
* @see Signature * @see Signature
*/ */
public abstract class Attribute implements Cloneable, Node, Serializable { public abstract class Attribute implements Cloneable, Node, Serializable {
protected int name_index; // Points to attribute name in constant pool /**
protected int length; // Content length of attribute field *
protected byte tag; // Tag to distiguish subclasses */
protected ConstantPool constant_pool; private static final long serialVersionUID = 1L;
protected int name_index; // Points to attribute name in constant pool
protected int length; // Content length of attribute field
protected byte tag; // Tag to distiguish subclasses
protected ConstantPool constant_pool;
protected Attribute(byte tag, int name_index, int length,
ConstantPool constant_pool) {
this.tag = tag;
this.name_index = name_index;
this.length = length;
this.constant_pool = constant_pool;
}
protected Attribute(byte tag, int name_index, int length, ConstantPool constant_pool) { /**
this.tag = tag; * Called by objects that are traversing the nodes of the tree implicitely
this.name_index = name_index; * defined by the contents of a Java class. I.e., the hierarchy of methods,
this.length = length; * fields, attributes, etc. spawns a tree of objects.
this.constant_pool = constant_pool; *
} * @param v
* Visitor object
*/
@Override
public abstract void accept(Visitor v);
/**
* Dump attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
public void dump(DataOutputStream file) throws IOException {
file.writeShort(name_index);
file.writeInt(length);
}
/** private static Map<String, AttributeReader> readers = new HashMap<String, AttributeReader>();
* Called by objects that are traversing the nodes of the tree implicitely
* defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v Visitor object
*/
public abstract void accept( Visitor v );
/**
* Add an Attribute reader capable of parsing (user-defined) attributes
* named "name". You should not add readers for the standard attributes such
* as "LineNumberTable", because those are handled internally.
*
* @param name
* the name of the attribute as stored in the class file
* @param r
* the reader object
*/
public static void addAttributeReader(String name, AttributeReader r) {
readers.put(name, r);
}
/** /**
* Dump attribute to file stream in binary format. * Remove attribute reader
* *
* @param file Output file stream * @param name
* @throws IOException * the name of the attribute as stored in the class file
*/ */
public void dump( DataOutputStream file ) throws IOException { public static void removeAttributeReader(String name) {
file.writeShort(name_index); readers.remove(name);
file.writeInt(length); }
}
private static Map readers = new HashMap(); /*
* Class method reads one attribute from the input data stream. This method
* must not be accessible from the outside. It is called by the Field and
* Method constructor methods.
*
* @see Field
*
* @see Method
*
* @param file Input stream
*
* @param constant_pool Array of constants
*
* @return Attribute
*
* @throws IOException
*
* @throws ClassFormatException
*/
public static final Attribute readAttribute(DataInputStream file,
ConstantPool constant_pool) throws IOException,
ClassFormatException {
ConstantUtf8 c;
String name;
int name_index;
int length;
byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute
// Get class name from constant pool via `name_index' indirection
name_index = file.readUnsignedShort();
c = (ConstantUtf8) constant_pool.getConstant(name_index,
Constants.CONSTANT_Utf8);
name = c.getBytes();
// Length of data in bytes
length = file.readInt();
// Compare strings to find known attribute
for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++) {
if (name.equals(Constants.ATTRIBUTE_NAMES[i])) {
tag = i; // found!
break;
}
}
// Call proper constructor, depending on `tag'
switch (tag) {
case Constants.ATTR_UNKNOWN:
AttributeReader r = readers.get(name);
if (r != null) {
return r.createAttribute(name_index, length, file,
constant_pool);
}
return new Unknown(name_index, length, file, constant_pool);
case Constants.ATTR_CONSTANT_VALUE:
return new ConstantValue(name_index, length, file, constant_pool);
case Constants.ATTR_SOURCE_FILE:
return new SourceFile(name_index, length, file, constant_pool);
case Constants.ATTR_CODE:
return new Code(name_index, length, file, constant_pool);
case Constants.ATTR_EXCEPTIONS:
return new ExceptionTable(name_index, length, file, constant_pool);
case Constants.ATTR_LINE_NUMBER_TABLE:
return new LineNumberTable(name_index, length, file, constant_pool);
case Constants.ATTR_LOCAL_VARIABLE_TABLE:
return new LocalVariableTable(name_index, length, file,
constant_pool);
case Constants.ATTR_INNER_CLASSES:
return new InnerClasses(name_index, length, file, constant_pool);
case Constants.ATTR_SYNTHETIC:
return new Synthetic(name_index, length, file, constant_pool);
case Constants.ATTR_DEPRECATED:
return new Deprecated(name_index, length, file, constant_pool);
case Constants.ATTR_PMG:
return new PMGClass(name_index, length, file, constant_pool);
case Constants.ATTR_SIGNATURE:
return new Signature(name_index, length, file, constant_pool);
case Constants.ATTR_STACK_MAP:
return new StackMap(name_index, length, file, constant_pool);
// case Constants.ATTR_RUNTIMEVISIBLE_ANNOTATIONS:
// return new RuntimeVisibleAnnotations(name_index, length, file,
// constant_pool);
// case Constants.ATTR_RUNTIMEINVISIBLE_ANNOTATIONS:
// return new RuntimeInvisibleAnnotations(name_index, length, file,
// constant_pool);
// case Constants.ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS:
// return new RuntimeVisibleParameterAnnotations(name_index, length,
// file, constant_pool);
// case Constants.ATTR_RUNTIMEINVISIBLE_PARAMETER_ANNOTATIONS:
// return new RuntimeInvisibleParameterAnnotations(name_index,
// length, file, constant_pool);
// case Constants.ATTR_ANNOTATION_DEFAULT:
// return new AnnotationDefault(name_index, length, file,
// constant_pool);
default: // Never reached
throw new IllegalStateException("Ooops! default case reached.");
}
}
/**
* @return Length of attribute field in bytes.
*/
public final int getLength() {
return length;
}
/** Add an Attribute reader capable of parsing (user-defined) attributes /**
* named "name". You should not add readers for the standard attributes * @param length
* such as "LineNumberTable", because those are handled internally. * length in bytes.
* */
* @param name the name of the attribute as stored in the class file public final void setLength(int length) {
* @param r the reader object this.length = length;
*/ }
public static void addAttributeReader( String name, AttributeReader r ) {
readers.put(name, r);
}
/**
* @param name_index
* of attribute.
*/
public final void setNameIndex(int name_index) {
this.name_index = name_index;
}
/** Remove attribute reader /**
* * @return Name index in constant pool of attribute name.
* @param name the name of the attribute as stored in the class file */
*/ public final int getNameIndex() {
public static void removeAttributeReader( String name ) { return name_index;
readers.remove(name); }
}
/**
* @return Tag of attribute, i.e., its type. Value may not be altered, thus
* there is no setTag() method.
*/
public final byte getTag() {
return tag;
}
/* Class method reads one attribute from the input data stream. /**
* This method must not be accessible from the outside. It is * @return Constant pool used by this object.
* called by the Field and Method constructor methods. * @see ConstantPool
* */
* @see Field public final ConstantPool getConstantPool() {
* @see Method return constant_pool;
* @param file Input stream }
* @param constant_pool Array of constants
* @return Attribute
* @throws IOException
* @throws ClassFormatException
*/
public static final Attribute readAttribute( DataInputStream file, ConstantPool constant_pool )
throws IOException, ClassFormatException {
ConstantUtf8 c;
String name;
int name_index;
int length;
byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute
// Get class name from constant pool via `name_index' indirection
name_index = file.readUnsignedShort();
c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
name = c.getBytes();
// Length of data in bytes
length = file.readInt();
// Compare strings to find known attribute
for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++) {
if (name.equals(Constants.ATTRIBUTE_NAMES[i])) {
tag = i; // found!
break;
}
}
// Call proper constructor, depending on `tag'
switch (tag) {
case Constants.ATTR_UNKNOWN:
AttributeReader r = (AttributeReader) readers.get(name);
if (r != null) {
return r.createAttribute(name_index, length, file, constant_pool);
}
return new Unknown(name_index, length, file, constant_pool);
case Constants.ATTR_CONSTANT_VALUE:
return new ConstantValue(name_index, length, file, constant_pool);
case Constants.ATTR_SOURCE_FILE:
return new SourceFile(name_index, length, file, constant_pool);
case Constants.ATTR_CODE:
return new Code(name_index, length, file, constant_pool);
case Constants.ATTR_EXCEPTIONS:
return new ExceptionTable(name_index, length, file, constant_pool);
case Constants.ATTR_LINE_NUMBER_TABLE:
return new LineNumberTable(name_index, length, file, constant_pool);
case Constants.ATTR_LOCAL_VARIABLE_TABLE:
return new LocalVariableTable(name_index, length, file, constant_pool);
case Constants.ATTR_INNER_CLASSES:
return new InnerClasses(name_index, length, file, constant_pool);
case Constants.ATTR_SYNTHETIC:
return new Synthetic(name_index, length, file, constant_pool);
case Constants.ATTR_DEPRECATED:
return new Deprecated(name_index, length, file, constant_pool);
case Constants.ATTR_PMG:
return new PMGClass(name_index, length, file, constant_pool);
case Constants.ATTR_SIGNATURE:
return new Signature(name_index, length, file, constant_pool);
case Constants.ATTR_STACK_MAP:
return new StackMap(name_index, length, file, constant_pool);
// case Constants.ATTR_RUNTIMEVISIBLE_ANNOTATIONS:
// return new RuntimeVisibleAnnotations(name_index, length, file, constant_pool);
// case Constants.ATTR_RUNTIMEINVISIBLE_ANNOTATIONS:
// return new RuntimeInvisibleAnnotations(name_index, length, file, constant_pool);
// case Constants.ATTR_RUNTIMEVISIBLE_PARAMETER_ANNOTATIONS:
// return new RuntimeVisibleParameterAnnotations(name_index, length, file, constant_pool);
// case Constants.ATTR_RUNTIMEINVISIBLE_PARAMETER_ANNOTATIONS:
// return new RuntimeInvisibleParameterAnnotations(name_index, length, file, constant_pool);
// case Constants.ATTR_ANNOTATION_DEFAULT:
// return new AnnotationDefault(name_index, length, file, constant_pool);
default: // Never reached
throw new IllegalStateException("Ooops! default case reached.");
}
}
/**
* @param constant_pool
* Constant pool to be used for this object.
* @see ConstantPool
*/
public final void setConstantPool(ConstantPool constant_pool) {
this.constant_pool = constant_pool;
}
/** /**
* @return Length of attribute field in bytes. * Use copy() if you want to have a deep copy(), i.e., with all references
*/ * copied correctly.
public final int getLength() { *
return length; * @return shallow copy of this attribute
} */
@Override
public Object clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace(); // Never occurs
}
return o;
}
/**
* @return deep copy of this attribute
*/
public abstract Attribute copy(ConstantPool _constant_pool);
/** /**
* @param length length in bytes. * @return attribute name.
*/ */
public final void setLength( int length ) { @Override
this.length = length; public String toString() {
} return Constants.ATTRIBUTE_NAMES[tag];
}
/**
* @param name_index of attribute.
*/
public final void setNameIndex( int name_index ) {
this.name_index = name_index;
}
/**
* @return Name index in constant pool of attribute name.
*/
public final int getNameIndex() {
return name_index;
}
/**
* @return Tag of attribute, i.e., its type. Value may not be altered, thus
* there is no setTag() method.
*/
public final byte getTag() {
return tag;
}
/**
* @return Constant pool used by this object.
* @see ConstantPool
*/
public final ConstantPool getConstantPool() {
return constant_pool;
}
/**
* @param constant_pool Constant pool to be used for this object.
* @see ConstantPool
*/
public final void setConstantPool( ConstantPool constant_pool ) {
this.constant_pool = constant_pool;
}
/**
* Use copy() if you want to have a deep copy(), i.e., with all references
* copied correctly.
*
* @return shallow copy of this attribute
*/
public Object clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace(); // Never occurs
}
return o;
}
/**
* @return deep copy of this attribute
*/
public abstract Attribute copy( ConstantPool _constant_pool );
/**
* @return attribute name.
*/
public String toString() {
return Constants.ATTRIBUTE_NAMES[tag];
}
} }

View File

@ -18,41 +18,39 @@ package org.apache.bcel.classfile;
/** /**
* Unknown (non-standard) attributes may be read via user-defined factory * Unknown (non-standard) attributes may be read via user-defined factory
* objects that can be registered with the Attribute.addAttributeReader * objects that can be registered with the Attribute.addAttributeReader method.
* method. These factory objects should implement this interface. * These factory objects should implement this interface.
*
* @see Attribute * @see Attribute
* @version $Id: AttributeReader.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: AttributeReader.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public interface AttributeReader { public interface AttributeReader {
/** /**
When this attribute reader is added via the static method * When this attribute reader is added via the static method
Attribute.addAttributeReader, an attribute name is associated with it. * Attribute.addAttributeReader, an attribute name is associated with it. As
As the class file parser parses attributes, it will call various * the class file parser parses attributes, it will call various
AttributeReaders based on the name of the attributes it is * AttributeReaders based on the name of the attributes it is constructing.
constructing. *
* @param name_index
@param name_index An index into the constant pool, indexing a * An index into the constant pool, indexing a ConstantUtf8 that
ConstantUtf8 that represents the name of the attribute. * represents the name of the attribute.
* @param length
@param length The length of the data contained in the attribute. This * The length of the data contained in the attribute. This is
is written into the constant pool and should agree with what the * written into the constant pool and should agree with what the
factory expects the length to be. * factory expects the length to be.
* @param file
@param file This is the data input stream that the factory needs to read * This is the data input stream that the factory needs to read
its data from. * its data from.
* @param constant_pool
@param constant_pool This is the constant pool associated with the * This is the constant pool associated with the Attribute that
Attribute that we are constructing. * we are constructing.
* @return The user-defined AttributeReader should take this data and use it
@return The user-defined AttributeReader should take this data and use * to construct an attribute. In the case of errors, a null can be
it to construct an attribute. In the case of errors, a null can be * returned which will cause the parsing of the class file to fail.
returned which will cause the parsing of the class file to fail. * @see Attribute#addAttributeReader(String, AttributeReader )
*/
@see Attribute#addAttributeReader( String, AttributeReader ) public Attribute createAttribute(int name_index, int length,
*/ java.io.DataInputStream file, ConstantPool constant_pool);
public Attribute createAttribute( int name_index, int length, java.io.DataInputStream file,
ConstantPool constant_pool );
} }

View File

@ -16,22 +16,25 @@
*/ */
package org.apache.bcel.classfile; package org.apache.bcel.classfile;
/** /**
* Thrown when the BCEL attempts to read a class file and determines * Thrown when the BCEL attempts to read a class file and determines that the
* that the file is malformed or otherwise cannot be interpreted as a * file is malformed or otherwise cannot be interpreted as a class file.
* class file. *
*
* @version $Id: ClassFormatException.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ClassFormatException.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ClassFormatException extends RuntimeException { public class ClassFormatException extends RuntimeException {
public ClassFormatException() { /**
super(); *
} */
private static final long serialVersionUID = 1L;
public ClassFormatException() {
super();
}
public ClassFormatException(String s) { public ClassFormatException(String s) {
super(s); super(s);
} }
} }

View File

@ -26,270 +26,283 @@ import java.util.zip.ZipFile;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* Wrapper class that parses a given Java .class file. The method <A * Wrapper class that parses a given Java .class file. The method <A href
* href ="#parse">parse</A> returns a <A href ="JavaClass.html"> * ="#parse">parse</A> returns a <A href ="JavaClass.html"> JavaClass</A> object
* JavaClass</A> object on success. When an I/O error or an * on success. When an I/O error or an inconsistency occurs an appropiate
* inconsistency occurs an appropiate exception is propagated back to * exception is propagated back to the caller.
* the caller. *
* * The structure and the names comply, except for a few conveniences, exactly
* The structure and the names comply, except for a few conveniences, * with the <A href="ftp://java.sun.com/docs/specs/vmspec.ps"> JVM specification
* exactly with the <A href="ftp://java.sun.com/docs/specs/vmspec.ps"> * 1.0</a>. See this paper for further details about the structure of a bytecode
* JVM specification 1.0</a>. See this paper for * file.
* further details about the structure of a bytecode file. *
*
* @version $Id: ClassParser.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ClassParser.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class ClassParser { public final class ClassParser {
private DataInputStream file; private DataInputStream file;
private boolean fileOwned; private boolean fileOwned;
private String file_name; private String file_name;
private String zip_file; private String zip_file;
private int class_name_index, superclass_name_index; private int class_name_index, superclass_name_index;
private int major, minor; // Compiler version private int major, minor; // Compiler version
private int access_flags; // Access rights of parsed class private int access_flags; // Access rights of parsed class
private int[] interfaces; // Names of implemented interfaces private int[] interfaces; // Names of implemented interfaces
private ConstantPool constant_pool; // collection of constants private ConstantPool constant_pool; // collection of constants
private Field[] fields; // class fields, i.e., its variables private Field[] fields; // class fields, i.e., its variables
private Method[] methods; // methods defined in the class private Method[] methods; // methods defined in the class
private Attribute[] attributes; // attributes defined in the class private Attribute[] attributes; // attributes defined in the class
private boolean is_zip; // Loaded from zip file private boolean is_zip; // Loaded from zip file
private static final int BUFSIZE = 8192; private static final int BUFSIZE = 8192;
/**
* Parse class from the given stream.
*
* @param file
* Input stream
* @param file_name
* File name
*/
public ClassParser(InputStream file, String file_name) {
this.file_name = file_name;
fileOwned = false;
String clazz = file.getClass().getName(); // Not a very clean solution
// ...
is_zip = clazz.startsWith("java.util.zip.")
|| clazz.startsWith("java.util.jar.");
if (file instanceof DataInputStream) {
this.file = (DataInputStream) file;
} else {
this.file = new DataInputStream(new BufferedInputStream(file,
BUFSIZE));
}
}
/** /**
* Parse class from the given stream. * Parse class from given .class file.
* *
* @param file Input stream * @param file_name
* @param file_name File name * file name
*/ */
public ClassParser(InputStream file, String file_name) { public ClassParser(String file_name) throws IOException {
this.file_name = file_name; is_zip = false;
fileOwned = false; this.file_name = file_name;
String clazz = file.getClass().getName(); // Not a very clean solution ... fileOwned = true;
is_zip = clazz.startsWith("java.util.zip.") || clazz.startsWith("java.util.jar."); }
if (file instanceof DataInputStream) {
this.file = (DataInputStream) file;
} else {
this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE));
}
}
/**
* Parse class from given .class file in a ZIP-archive
*
* @param zip_file
* zip file name
* @param file_name
* file name
*/
public ClassParser(String zip_file, String file_name) {
is_zip = true;
fileOwned = true;
this.zip_file = zip_file;
this.file_name = file_name;
}
/** Parse class from given .class file. /**
* * Parse the given Java class file and return an object that represents the
* @param file_name file name * contained data, i.e., constants, methods, fields and commands. A
*/ * <em>ClassFormatException</em> is raised, if the file is not a valid
public ClassParser(String file_name) throws IOException { * .class file. (This does not include verification of the byte code as it
is_zip = false; * is performed by the java interpreter).
this.file_name = file_name; *
fileOwned = true; * @return Class object representing the parsed class file
} * @throws IOException
* @throws ClassFormatException
*/
public JavaClass parse() throws IOException, ClassFormatException {
ZipFile zip = null;
try {
if (fileOwned) {
if (is_zip) {
zip = new ZipFile(zip_file);
ZipEntry entry = zip.getEntry(file_name);
file = new DataInputStream(new BufferedInputStream(
zip.getInputStream(entry), BUFSIZE));
} else {
file = new DataInputStream(new BufferedInputStream(
new FileInputStream(file_name), BUFSIZE));
}
}
/****************** Read headers ********************************/
// Check magic tag of class file
readID();
// Get compiler version
readVersion();
/****************** Read constant pool and related **************/
// Read constant pool entries
readConstantPool();
// Get class information
readClassInfo();
// Get interface information, i.e., implemented interfaces
readInterfaces();
/****************** Read class fields and methods ***************/
// Read class fields, i.e., the variables of the class
readFields();
// Read class methods, i.e., the functions in the class
readMethods();
// Read class attributes
readAttributes();
// Check for unknown variables
// Unknown[] u = Unknown.getUnknownAttributes();
// for(int i=0; i < u.length; i++)
// System.err.println("WARNING: " + u[i]);
// Everything should have been read now
// if(file.available() > 0) {
// int bytes = file.available();
// byte[] buf = new byte[bytes];
// file.read(buf);
// if(!(is_zip && (buf.length == 1))) {
// System.err.println("WARNING: Trailing garbage at end of " +
// file_name);
// System.err.println(bytes + " extra bytes: " +
// Utility.toHexString(buf));
// }
// }
} finally {
// Read everything of interest, so close the file
if (fileOwned) {
file.close();
if (zip != null) {
zip.close();
}
}
}
// Return the information we have gathered in a new object
return new JavaClass(class_name_index, superclass_name_index,
file_name, major, minor, access_flags, constant_pool,
interfaces, fields, methods, attributes, is_zip ? JavaClass.ZIP
: JavaClass.FILE);
}
/**
* Read information about the attributes of the class.
*
* @throws IOException
* @throws ClassFormatException
*/
private final void readAttributes() throws IOException,
ClassFormatException {
int attributes_count;
attributes_count = file.readUnsignedShort();
attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
attributes[i] = Attribute.readAttribute(file, constant_pool);
}
}
/** Parse class from given .class file in a ZIP-archive /**
* * Read information about the class and its super class.
* @param zip_file zip file name *
* @param file_name file name * @throws IOException
*/ * @throws ClassFormatException
public ClassParser(String zip_file, String file_name) { */
is_zip = true; private final void readClassInfo() throws IOException, ClassFormatException {
fileOwned = true; access_flags = file.readUnsignedShort();
this.zip_file = zip_file; /*
this.file_name = file_name; * Interfaces are implicitely abstract, the flag should be set according
} * to the JVM specification.
*/
if ((access_flags & Constants.ACC_INTERFACE) != 0) {
access_flags |= Constants.ACC_ABSTRACT;
}
if (((access_flags & Constants.ACC_ABSTRACT) != 0)
&& ((access_flags & Constants.ACC_FINAL) != 0)) {
throw new ClassFormatException(
"Class can't be both final and abstract");
}
class_name_index = file.readUnsignedShort();
superclass_name_index = file.readUnsignedShort();
}
/**
* Read constant pool entries.
*
* @throws IOException
* @throws ClassFormatException
*/
private final void readConstantPool() throws IOException,
ClassFormatException {
constant_pool = new ConstantPool(file);
}
/** /**
* Parse the given Java class file and return an object that represents * Read information about the fields of the class, i.e., its variables.
* the contained data, i.e., constants, methods, fields and commands. *
* A <em>ClassFormatException</em> is raised, if the file is not a valid * @throws IOException
* .class file. (This does not include verification of the byte code as it * @throws ClassFormatException
* is performed by the java interpreter). */
* private final void readFields() throws IOException, ClassFormatException {
* @return Class object representing the parsed class file int fields_count;
* @throws IOException fields_count = file.readUnsignedShort();
* @throws ClassFormatException fields = new Field[fields_count];
*/ for (int i = 0; i < fields_count; i++) {
public JavaClass parse() throws IOException, ClassFormatException { fields[i] = new Field(file, constant_pool);
ZipFile zip = null; }
try { }
if (fileOwned) {
if (is_zip) {
zip = new ZipFile(zip_file);
ZipEntry entry = zip.getEntry(file_name);
file = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry),
BUFSIZE));
} else {
file = new DataInputStream(new BufferedInputStream(new FileInputStream(
file_name), BUFSIZE));
}
}
/****************** Read headers ********************************/
// Check magic tag of class file
readID();
// Get compiler version
readVersion();
/****************** Read constant pool and related **************/
// Read constant pool entries
readConstantPool();
// Get class information
readClassInfo();
// Get interface information, i.e., implemented interfaces
readInterfaces();
/****************** Read class fields and methods ***************/
// Read class fields, i.e., the variables of the class
readFields();
// Read class methods, i.e., the functions in the class
readMethods();
// Read class attributes
readAttributes();
// Check for unknown variables
//Unknown[] u = Unknown.getUnknownAttributes();
//for(int i=0; i < u.length; i++)
// System.err.println("WARNING: " + u[i]);
// Everything should have been read now
// if(file.available() > 0) {
// int bytes = file.available();
// byte[] buf = new byte[bytes];
// file.read(buf);
// if(!(is_zip && (buf.length == 1))) {
// System.err.println("WARNING: Trailing garbage at end of " + file_name);
// System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf));
// }
// }
} finally {
// Read everything of interest, so close the file
if (fileOwned) {
file.close();
if (zip != null) {
zip.close();
}
}
}
// Return the information we have gathered in a new object
return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor,
access_flags, constant_pool, interfaces, fields, methods, attributes, is_zip
? JavaClass.ZIP
: JavaClass.FILE);
}
/******************** Private utility methods **********************/
/**
* Check whether the header of the file is ok. Of course, this has to be the
* first action on successive file reads.
*
* @throws IOException
* @throws ClassFormatException
*/
private final void readID() throws IOException, ClassFormatException {
int magic = 0xCAFEBABE;
if (file.readInt() != magic) {
throw new ClassFormatException(file_name
+ " is not a Java .class file");
}
}
/** /**
* Read information about the attributes of the class. * Read information about the interfaces implemented by this class.
* @throws IOException *
* @throws ClassFormatException * @throws IOException
*/ * @throws ClassFormatException
private final void readAttributes() throws IOException, ClassFormatException { */
int attributes_count; private final void readInterfaces() throws IOException,
attributes_count = file.readUnsignedShort(); ClassFormatException {
attributes = new Attribute[attributes_count]; int interfaces_count;
for (int i = 0; i < attributes_count; i++) { interfaces_count = file.readUnsignedShort();
attributes[i] = Attribute.readAttribute(file, constant_pool); interfaces = new int[interfaces_count];
} for (int i = 0; i < interfaces_count; i++) {
} interfaces[i] = file.readUnsignedShort();
}
}
/**
* Read information about the methods of the class.
*
* @throws IOException
* @throws ClassFormatException
*/
private final void readMethods() throws IOException, ClassFormatException {
int methods_count;
methods_count = file.readUnsignedShort();
methods = new Method[methods_count];
for (int i = 0; i < methods_count; i++) {
methods[i] = new Method(file, constant_pool);
}
}
/** /**
* Read information about the class and its super class. * Read major and minor version of compiler which created the file.
* @throws IOException *
* @throws ClassFormatException * @throws IOException
*/ * @throws ClassFormatException
private final void readClassInfo() throws IOException, ClassFormatException { */
access_flags = file.readUnsignedShort(); private final void readVersion() throws IOException, ClassFormatException {
/* Interfaces are implicitely abstract, the flag should be set minor = file.readUnsignedShort();
* according to the JVM specification. major = file.readUnsignedShort();
*/ }
if ((access_flags & Constants.ACC_INTERFACE) != 0) {
access_flags |= Constants.ACC_ABSTRACT;
}
if (((access_flags & Constants.ACC_ABSTRACT) != 0)
&& ((access_flags & Constants.ACC_FINAL) != 0)) {
throw new ClassFormatException("Class can't be both final and abstract");
}
class_name_index = file.readUnsignedShort();
superclass_name_index = file.readUnsignedShort();
}
/**
* Read constant pool entries.
* @throws IOException
* @throws ClassFormatException
*/
private final void readConstantPool() throws IOException, ClassFormatException {
constant_pool = new ConstantPool(file);
}
/**
* Read information about the fields of the class, i.e., its variables.
* @throws IOException
* @throws ClassFormatException
*/
private final void readFields() throws IOException, ClassFormatException {
int fields_count;
fields_count = file.readUnsignedShort();
fields = new Field[fields_count];
for (int i = 0; i < fields_count; i++) {
fields[i] = new Field(file, constant_pool);
}
}
/******************** Private utility methods **********************/
/**
* Check whether the header of the file is ok.
* Of course, this has to be the first action on successive file reads.
* @throws IOException
* @throws ClassFormatException
*/
private final void readID() throws IOException, ClassFormatException {
int magic = 0xCAFEBABE;
if (file.readInt() != magic) {
throw new ClassFormatException(file_name + " is not a Java .class file");
}
}
/**
* Read information about the interfaces implemented by this class.
* @throws IOException
* @throws ClassFormatException
*/
private final void readInterfaces() throws IOException, ClassFormatException {
int interfaces_count;
interfaces_count = file.readUnsignedShort();
interfaces = new int[interfaces_count];
for (int i = 0; i < interfaces_count; i++) {
interfaces[i] = file.readUnsignedShort();
}
}
/**
* Read information about the methods of the class.
* @throws IOException
* @throws ClassFormatException
*/
private final void readMethods() throws IOException, ClassFormatException {
int methods_count;
methods_count = file.readUnsignedShort();
methods = new Method[methods_count];
for (int i = 0; i < methods_count; i++) {
methods[i] = new Method(file, constant_pool);
}
}
/**
* Read major and minor version of compiler which created the file.
* @throws IOException
* @throws ClassFormatException
*/
private final void readVersion() throws IOException, ClassFormatException {
minor = file.readUnsignedShort();
major = file.readUnsignedShort();
}
} }

View File

@ -21,332 +21,351 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents a chunk of Java byte code contained in a * This class represents a chunk of Java byte code contained in a method. It is
* method. It is instantiated by the * instantiated by the <em>Attribute.readAttribute()</em> method. A
* <em>Attribute.readAttribute()</em> method. A <em>Code</em> * <em>Code</em> attribute contains informations about operand stack, local
* attribute contains informations about operand stack, local * variables, byte code and the exceptions handled within this method.
* variables, byte code and the exceptions handled within this *
* method.
*
* This attribute has attributes itself, namely <em>LineNumberTable</em> which * This attribute has attributes itself, namely <em>LineNumberTable</em> which
* is used for debugging purposes and <em>LocalVariableTable</em> which * is used for debugging purposes and <em>LocalVariableTable</em> which contains
* contains information about the local variables. * information about the local variables.
* *
* @version $Id: Code.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Code.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute * @see Attribute
* @see CodeException * @see CodeException
* @see LineNumberTable * @see LineNumberTable
* @see LocalVariableTable * @see LocalVariableTable
*/ */
public final class Code extends Attribute { public final class Code extends Attribute {
private int max_stack; // Maximum size of stack used by this method /**
private int max_locals; // Number of local variables *
private int code_length; // Length of code in bytes */
private byte[] code; // Actual byte code private static final long serialVersionUID = 1L;
private int exception_table_length; private int max_stack; // Maximum size of stack used by this method
private CodeException[] exception_table; // Table of handled exceptions private int max_locals; // Number of local variables
private int attributes_count; // Attributes of code: LineNumber private int code_length; // Length of code in bytes
private Attribute[] attributes; // or LocalVariable private byte[] code; // Actual byte code
private int exception_table_length;
private CodeException[] exception_table; // Table of handled exceptions
private int attributes_count; // Attributes of code: LineNumber
private Attribute[] attributes; // or LocalVariable
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use copy() for a physical copy.
*/
public Code(Code c) {
this(c.getNameIndex(), c.getLength(), c.getMaxStack(),
c.getMaxLocals(), c.getCode(), c.getExceptionTable(), c
.getAttributes(), c.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * @param name_index
* references (shallow copy). Use copy() for a physical copy. * Index pointing to the name <em>Code</em>
*/ * @param length
public Code(Code c) { * Content length in bytes
this(c.getNameIndex(), c.getLength(), c.getMaxStack(), c.getMaxLocals(), c.getCode(), c * @param file
.getExceptionTable(), c.getAttributes(), c.getConstantPool()); * Input stream
} * @param constant_pool
* Array of constants
*/
Code(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
// Initialize with some default values which will be overwritten later
this(name_index, length, file.readUnsignedShort(), file
.readUnsignedShort(), (byte[]) null, (CodeException[]) null,
(Attribute[]) null, constant_pool);
code_length = file.readInt();
code = new byte[code_length]; // Read byte code
file.readFully(code);
/*
* Read exception table that contains all regions where an exception
* handler is active, i.e., a try { ... } catch() block.
*/
exception_table_length = file.readUnsignedShort();
exception_table = new CodeException[exception_table_length];
for (int i = 0; i < exception_table_length; i++) {
exception_table[i] = new CodeException(file);
}
/*
* Read all attributes, currently `LineNumberTable' and
* `LocalVariableTable'
*/
attributes_count = file.readUnsignedShort();
attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
attributes[i] = Attribute.readAttribute(file, constant_pool);
}
/*
* Adjust length, because of setAttributes in this(), s.b. length is
* incorrect, because it didn't take the internal attributes into
* account yet! Very subtle bug, fixed in 3.1.1.
*/
this.length = length;
}
/**
* @param name_index
* Index pointing to the name <em>Code</em>
* @param length
* Content length in bytes
* @param max_stack
* Maximum size of stack
* @param max_locals
* Number of local variables
* @param code
* Actual byte code
* @param exception_table
* Table of handled exceptions
* @param attributes
* Attributes of code: LineNumber or LocalVariable
* @param constant_pool
* Array of constants
*/
public Code(int name_index, int length, int max_stack, int max_locals,
byte[] code, CodeException[] exception_table,
Attribute[] attributes, ConstantPool constant_pool) {
super(Constants.ATTR_CODE, name_index, length, constant_pool);
this.max_stack = max_stack;
this.max_locals = max_locals;
setCode(code);
setExceptionTable(exception_table);
setAttributes(attributes); // Overwrites length!
}
/** /**
* @param name_index Index pointing to the name <em>Code</em> * Called by objects that are traversing the nodes of the tree implicitely
* @param length Content length in bytes * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param file Input stream * fields, attributes, etc. spawns a tree of objects.
* @param constant_pool Array of constants *
*/ * @param v
Code(int name_index, int length, DataInputStream file, ConstantPool constant_pool) * Visitor object
throws IOException { */
// Initialize with some default values which will be overwritten later @Override
this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), (byte[]) null, public void accept(Visitor v) {
(CodeException[]) null, (Attribute[]) null, constant_pool); v.visitCode(this);
code_length = file.readInt(); }
code = new byte[code_length]; // Read byte code
file.readFully(code);
/* Read exception table that contains all regions where an exception
* handler is active, i.e., a try { ... } catch() block.
*/
exception_table_length = file.readUnsignedShort();
exception_table = new CodeException[exception_table_length];
for (int i = 0; i < exception_table_length; i++) {
exception_table[i] = new CodeException(file);
}
/* Read all attributes, currently `LineNumberTable' and
* `LocalVariableTable'
*/
attributes_count = file.readUnsignedShort();
attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
attributes[i] = Attribute.readAttribute(file, constant_pool);
}
/* Adjust length, because of setAttributes in this(), s.b. length
* is incorrect, because it didn't take the internal attributes
* into account yet! Very subtle bug, fixed in 3.1.1.
*/
this.length = length;
}
/**
* Dump code attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(max_stack);
file.writeShort(max_locals);
file.writeInt(code_length);
file.write(code, 0, code_length);
file.writeShort(exception_table_length);
for (int i = 0; i < exception_table_length; i++) {
exception_table[i].dump(file);
}
file.writeShort(attributes_count);
for (int i = 0; i < attributes_count; i++) {
attributes[i].dump(file);
}
}
/** /**
* @param name_index Index pointing to the name <em>Code</em> * @return Collection of code attributes.
* @param length Content length in bytes * @see Attribute
* @param max_stack Maximum size of stack */
* @param max_locals Number of local variables public final Attribute[] getAttributes() {
* @param code Actual byte code return attributes;
* @param exception_table Table of handled exceptions }
* @param attributes Attributes of code: LineNumber or LocalVariable
* @param constant_pool Array of constants
*/
public Code(int name_index, int length, int max_stack, int max_locals, byte[] code,
CodeException[] exception_table, Attribute[] attributes, ConstantPool constant_pool) {
super(Constants.ATTR_CODE, name_index, length, constant_pool);
this.max_stack = max_stack;
this.max_locals = max_locals;
setCode(code);
setExceptionTable(exception_table);
setAttributes(attributes); // Overwrites length!
}
/**
* @return LineNumberTable of Code, if it has one
*/
public LineNumberTable getLineNumberTable() {
for (int i = 0; i < attributes_count; i++) {
if (attributes[i] instanceof LineNumberTable) {
return (LineNumberTable) attributes[i];
}
}
return null;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return LocalVariableTable of Code, if it has one
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public LocalVariableTable getLocalVariableTable() {
* for (int i = 0; i < attributes_count; i++) {
* @param v Visitor object if (attributes[i] instanceof LocalVariableTable) {
*/ return (LocalVariableTable) attributes[i];
public void accept( Visitor v ) { }
v.visitCode(this); }
} return null;
}
/**
* @return Actual byte code of the method.
*/
public final byte[] getCode() {
return code;
}
/** /**
* Dump code attribute to file stream in binary format. * @return Table of handled exceptions.
* * @see CodeException
* @param file Output file stream */
* @throws IOException public final CodeException[] getExceptionTable() {
*/ return exception_table;
public final void dump( DataOutputStream file ) throws IOException { }
super.dump(file);
file.writeShort(max_stack);
file.writeShort(max_locals);
file.writeInt(code_length);
file.write(code, 0, code_length);
file.writeShort(exception_table_length);
for (int i = 0; i < exception_table_length; i++) {
exception_table[i].dump(file);
}
file.writeShort(attributes_count);
for (int i = 0; i < attributes_count; i++) {
attributes[i].dump(file);
}
}
/**
* @return Number of local variables.
*/
public final int getMaxLocals() {
return max_locals;
}
/** /**
* @return Collection of code attributes. * @return Maximum size of stack used by this method.
* @see Attribute */
*/ public final int getMaxStack() {
public final Attribute[] getAttributes() { return max_stack;
return attributes; }
}
/**
* @return the internal length of this code attribute (minus the first 6
* bytes) and excluding all its attributes
*/
private final int getInternalLength() {
return 2 /* max_stack */+ 2 /* max_locals */+ 4 /* code length */
+ code_length /* byte-code */
+ 2 /* exception-table length */
+ 8 * exception_table_length /* exception table */
+ 2 /* attributes count */;
}
/** /**
* @return LineNumberTable of Code, if it has one * @return the full size of this code attribute, minus its first 6 bytes,
*/ * including the size of all its contained attributes
public LineNumberTable getLineNumberTable() { */
for (int i = 0; i < attributes_count; i++) { private final int calculateLength() {
if (attributes[i] instanceof LineNumberTable) { int len = 0;
return (LineNumberTable) attributes[i]; for (int i = 0; i < attributes_count; i++) {
} len += attributes[i].length + 6 /* attribute header size */;
} }
return null; return len + getInternalLength();
} }
/**
* @param attributes
* the attributes to set for this Code
*/
public final void setAttributes(Attribute[] attributes) {
this.attributes = attributes;
attributes_count = (attributes == null) ? 0 : attributes.length;
length = calculateLength(); // Adjust length
}
/** /**
* @return LocalVariableTable of Code, if it has one * @param code
*/ * byte code
public LocalVariableTable getLocalVariableTable() { */
for (int i = 0; i < attributes_count; i++) { public final void setCode(byte[] code) {
if (attributes[i] instanceof LocalVariableTable) { this.code = code;
return (LocalVariableTable) attributes[i]; code_length = (code == null) ? 0 : code.length;
} }
}
return null;
}
/**
* @param exception_table
* exception table
*/
public final void setExceptionTable(CodeException[] exception_table) {
this.exception_table = exception_table;
exception_table_length = (exception_table == null) ? 0
: exception_table.length;
}
/** /**
* @return Actual byte code of the method. * @param max_locals
*/ * maximum number of local variables
public final byte[] getCode() { */
return code; public final void setMaxLocals(int max_locals) {
} this.max_locals = max_locals;
}
/**
* @param max_stack
* maximum stack size
*/
public final void setMaxStack(int max_stack) {
this.max_stack = max_stack;
}
/** /**
* @return Table of handled exceptions. * @return String representation of code chunk.
* @see CodeException */
*/ public final String toString(boolean verbose) {
public final CodeException[] getExceptionTable() { StringBuffer buf;
return exception_table; buf = new StringBuffer(100);
} buf.append("Code(max_stack = ")
.append(max_stack)
.append(", max_locals = ")
.append(max_locals)
.append(", code_length = ")
.append(code_length)
.append(")\n")
.append(Utility.codeToString(code, constant_pool, 0, -1,
verbose));
if (exception_table_length > 0) {
buf.append("\nException handler(s) = \n").append(
"From\tTo\tHandler\tType\n");
for (int i = 0; i < exception_table_length; i++) {
buf.append(exception_table[i].toString(constant_pool, verbose))
.append("\n");
}
}
if (attributes_count > 0) {
buf.append("\nAttribute(s) = \n");
for (int i = 0; i < attributes_count; i++) {
buf.append(attributes[i].toString()).append("\n");
}
}
return buf.toString();
}
/**
* @return String representation of code chunk.
*/
@Override
public final String toString() {
return toString(true);
}
/** /**
* @return Number of local variables. * @return deep copy of this attribute
*/ *
public final int getMaxLocals() { * @param _constant_pool
return max_locals; * the constant pool to duplicate
} */
@Override
public Attribute copy(ConstantPool _constant_pool) {
/** Code c = (Code) clone();
* @return Maximum size of stack used by this method. if (code != null) {
*/ c.code = new byte[code.length];
public final int getMaxStack() { System.arraycopy(code, 0, c.code, 0, code.length);
return max_stack; }
} c.constant_pool = _constant_pool;
c.exception_table = new CodeException[exception_table_length];
for (int i = 0; i < exception_table_length; i++) {
/** c.exception_table[i] = exception_table[i].copy();
* @return the internal length of this code attribute (minus the first 6 bytes) }
* and excluding all its attributes c.attributes = new Attribute[attributes_count];
*/ for (int i = 0; i < attributes_count; i++) {
private final int getInternalLength() { c.attributes[i] = attributes[i].copy(_constant_pool);
return 2 /*max_stack*/+ 2 /*max_locals*/+ 4 /*code length*/ }
+ code_length /*byte-code*/ return c;
+ 2 /*exception-table length*/ }
+ 8 * exception_table_length /* exception table */
+ 2 /* attributes count */;
}
/**
* @return the full size of this code attribute, minus its first 6 bytes,
* including the size of all its contained attributes
*/
private final int calculateLength() {
int len = 0;
for (int i = 0; i < attributes_count; i++) {
len += attributes[i].length + 6 /*attribute header size*/;
}
return len + getInternalLength();
}
/**
* @param attributes the attributes to set for this Code
*/
public final void setAttributes( Attribute[] attributes ) {
this.attributes = attributes;
attributes_count = (attributes == null) ? 0 : attributes.length;
length = calculateLength(); // Adjust length
}
/**
* @param code byte code
*/
public final void setCode( byte[] code ) {
this.code = code;
code_length = (code == null) ? 0 : code.length;
}
/**
* @param exception_table exception table
*/
public final void setExceptionTable( CodeException[] exception_table ) {
this.exception_table = exception_table;
exception_table_length = (exception_table == null) ? 0 : exception_table.length;
}
/**
* @param max_locals maximum number of local variables
*/
public final void setMaxLocals( int max_locals ) {
this.max_locals = max_locals;
}
/**
* @param max_stack maximum stack size
*/
public final void setMaxStack( int max_stack ) {
this.max_stack = max_stack;
}
/**
* @return String representation of code chunk.
*/
public final String toString( boolean verbose ) {
StringBuffer buf;
buf = new StringBuffer(100);
buf.append("Code(max_stack = ").append(max_stack).append(", max_locals = ").append(
max_locals).append(", code_length = ").append(code_length).append(")\n").append(
Utility.codeToString(code, constant_pool, 0, -1, verbose));
if (exception_table_length > 0) {
buf.append("\nException handler(s) = \n").append("From\tTo\tHandler\tType\n");
for (int i = 0; i < exception_table_length; i++) {
buf.append(exception_table[i].toString(constant_pool, verbose)).append("\n");
}
}
if (attributes_count > 0) {
buf.append("\nAttribute(s) = \n");
for (int i = 0; i < attributes_count; i++) {
buf.append(attributes[i].toString()).append("\n");
}
}
return buf.toString();
}
/**
* @return String representation of code chunk.
*/
public final String toString() {
return toString(true);
}
/**
* @return deep copy of this attribute
*
* @param _constant_pool the constant pool to duplicate
*/
public Attribute copy( ConstantPool _constant_pool ) {
Code c = (Code) clone();
if (code != null) {
c.code = new byte[code.length];
System.arraycopy(code, 0, c.code, 0, code.length);
}
c.constant_pool = _constant_pool;
c.exception_table = new CodeException[exception_table_length];
for (int i = 0; i < exception_table_length; i++) {
c.exception_table[i] = exception_table[i].copy();
}
c.attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
c.attributes[i] = attributes[i].copy(_constant_pool);
}
return c;
}
} }

View File

@ -24,191 +24,197 @@ import org.apache.bcel.Constants;
/** /**
* This class represents an entry in the exception table of the <em>Code</em> * This class represents an entry in the exception table of the <em>Code</em>
* attribute and is used only there. It contains a range in which a * attribute and is used only there. It contains a range in which a particular
* particular exception handler is active. * exception handler is active.
* *
* @version $Id: CodeException.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: CodeException.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code * @see Code
*/ */
public final class CodeException implements Cloneable, Constants, Node, Serializable { public final class CodeException implements Cloneable, Constants, Node,
Serializable {
private int start_pc; // Range in the code the exception handler is /**
private int end_pc; // active. start_pc is inclusive, end_pc exclusive *
private int handler_pc; /* Starting address of exception handler, i.e., */
* an offset from start of code. private static final long serialVersionUID = 1L;
*/ private int start_pc; // Range in the code the exception handler is
private int catch_type; /* If this is zero the handler catches any private int end_pc; // active. start_pc is inclusive, end_pc exclusive
* exception, otherwise it points to the private int handler_pc; /*
* exception class which is to be caught. * Starting address of exception handler, i.e., an
*/ * offset from start of code.
*/
private int catch_type; /*
* If this is zero the handler catches any
* exception, otherwise it points to the exception
* class which is to be caught.
*/
/**
* Initialize from another object.
*/
public CodeException(CodeException c) {
this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType());
}
/** /**
* Initialize from another object. * Construct object from file stream.
*/ *
public CodeException(CodeException c) { * @param file
this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); * Input stream
} * @throws IOException
*/
CodeException(DataInputStream file) throws IOException {
this(file.readUnsignedShort(), file.readUnsignedShort(), file
.readUnsignedShort(), file.readUnsignedShort());
}
/**
* @param start_pc
* Range in the code the exception handler is active, start_pc is
* inclusive while
* @param end_pc
* is exclusive
* @param handler_pc
* Starting address of exception handler, i.e., an offset from
* start of code.
* @param catch_type
* If zero the handler catches any exception, otherwise it points
* to the exception class which is to be caught.
*/
public CodeException(int start_pc, int end_pc, int handler_pc,
int catch_type) {
this.start_pc = start_pc;
this.end_pc = end_pc;
this.handler_pc = handler_pc;
this.catch_type = catch_type;
}
/** /**
* Construct object from file stream. * Called by objects that are traversing the nodes of the tree implicitely
* @param file Input stream * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @throws IOException * fields, attributes, etc. spawns a tree of objects.
*/ *
CodeException(DataInputStream file) throws IOException { * @param v
this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file * Visitor object
.readUnsignedShort()); */
} @Override
public void accept(Visitor v) {
v.visitCodeException(this);
}
/**
* Dump code exception to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
public final void dump(DataOutputStream file) throws IOException {
file.writeShort(start_pc);
file.writeShort(end_pc);
file.writeShort(handler_pc);
file.writeShort(catch_type);
}
/** /**
* @param start_pc Range in the code the exception handler is active, * @return 0, if the handler catches any exception, otherwise it points to
* start_pc is inclusive while * the exception class which is to be caught.
* @param end_pc is exclusive */
* @param handler_pc Starting address of exception handler, i.e., public final int getCatchType() {
* an offset from start of code. return catch_type;
* @param catch_type If zero the handler catches any }
* exception, otherwise it points to the exception class which is
* to be caught.
*/
public CodeException(int start_pc, int end_pc, int handler_pc, int catch_type) {
this.start_pc = start_pc;
this.end_pc = end_pc;
this.handler_pc = handler_pc;
this.catch_type = catch_type;
}
/**
* @return Exclusive end index of the region where the handler is active.
*/
public final int getEndPC() {
return end_pc;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return Starting address of exception handler, relative to the code.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final int getHandlerPC() {
* return handler_pc;
* @param v Visitor object }
*/
public void accept( Visitor v ) {
v.visitCodeException(this);
}
/**
* @return Inclusive start index of the region where the handler is active.
*/
public final int getStartPC() {
return start_pc;
}
/** /**
* Dump code exception to file stream in binary format. * @param catch_type
* * the type of exception that is caught
* @param file Output file stream */
* @throws IOException public final void setCatchType(int catch_type) {
*/ this.catch_type = catch_type;
public final void dump( DataOutputStream file ) throws IOException { }
file.writeShort(start_pc);
file.writeShort(end_pc);
file.writeShort(handler_pc);
file.writeShort(catch_type);
}
/**
* @param end_pc
* end of handled block
*/
public final void setEndPC(int end_pc) {
this.end_pc = end_pc;
}
/** /**
* @return 0, if the handler catches any exception, otherwise it points to * @param handler_pc
* the exception class which is to be caught. * where the actual code is
*/ */
public final int getCatchType() { public final void setHandlerPC(int handler_pc) {
return catch_type; this.handler_pc = handler_pc;
} }
/**
* @param start_pc
* start of handled block
*/
public final void setStartPC(int start_pc) {
this.start_pc = start_pc;
}
/** /**
* @return Exclusive end index of the region where the handler is active. * @return String representation.
*/ */
public final int getEndPC() { @Override
return end_pc; public final String toString() {
} return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc
+ ", handler_pc = " + handler_pc + ", catch_type = "
+ catch_type + ")";
}
/**
* @return String representation.
*/
public final String toString(ConstantPool cp, boolean verbose) {
String str;
if (catch_type == 0) {
str = "<Any exception>(0)";
} else {
str = Utility.compactClassName(
cp.getConstantString(catch_type, CONSTANT_Class), false)
+ (verbose ? "(" + catch_type + ")" : "");
}
return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str;
}
/** public final String toString(ConstantPool cp) {
* @return Starting address of exception handler, relative to the code. return toString(cp, true);
*/ }
public final int getHandlerPC() {
return handler_pc;
}
/**
/** * @return deep copy of this object
* @return Inclusive start index of the region where the handler is active. */
*/ public CodeException copy() {
public final int getStartPC() { try {
return start_pc; return (CodeException) clone();
} } catch (CloneNotSupportedException e) {
}
return null;
/** }
* @param catch_type the type of exception that is caught
*/
public final void setCatchType( int catch_type ) {
this.catch_type = catch_type;
}
/**
* @param end_pc end of handled block
*/
public final void setEndPC( int end_pc ) {
this.end_pc = end_pc;
}
/**
* @param handler_pc where the actual code is
*/
public final void setHandlerPC( int handler_pc ) {
this.handler_pc = handler_pc;
}
/**
* @param start_pc start of handled block
*/
public final void setStartPC( int start_pc ) {
this.start_pc = start_pc;
}
/**
* @return String representation.
*/
public final String toString() {
return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = "
+ handler_pc + ", catch_type = " + catch_type + ")";
}
/**
* @return String representation.
*/
public final String toString( ConstantPool cp, boolean verbose ) {
String str;
if (catch_type == 0) {
str = "<Any exception>(0)";
} else {
str = Utility.compactClassName(cp.getConstantString(catch_type, CONSTANT_Class), false)
+ (verbose ? "(" + catch_type + ")" : "");
}
return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str;
}
public final String toString( ConstantPool cp ) {
return toString(cp, true);
}
/**
* @return deep copy of this object
*/
public CodeException copy() {
try {
return (CodeException) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
} }

View File

@ -24,165 +24,168 @@ import org.apache.bcel.Constants;
import org.apache.bcel.util.BCELComparator; import org.apache.bcel.util.BCELComparator;
/** /**
* Abstract superclass for classes to represent the different constant types * Abstract superclass for classes to represent the different constant types in
* in the constant pool of a class file. The classes keep closely to * the constant pool of a class file. The classes keep closely to the JVM
* the JVM specification. * specification.
* *
* @version $Id: Constant.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Constant.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class Constant implements Cloneable, Node, Serializable { public abstract class Constant implements Cloneable, Node, Serializable {
private static BCELComparator _cmp = new BCELComparator() { /**
*
*/
private static final long serialVersionUID = 1L;
private static BCELComparator _cmp = new BCELComparator() {
public boolean equals( Object o1, Object o2 ) { @Override
Constant THIS = (Constant) o1; public boolean equals(Object o1, Object o2) {
Constant THAT = (Constant) o2; Constant THIS = (Constant) o1;
return THIS.toString().equals(THAT.toString()); Constant THAT = (Constant) o2;
} return THIS.toString().equals(THAT.toString());
}
@Override
public int hashCode(Object o) {
Constant THIS = (Constant) o;
return THIS.toString().hashCode();
}
};
/*
* In fact this tag is redundant since we can distinguish different
* `Constant' objects by their type, i.e., via `instanceof'. In some places
* we will use the tag for switch()es anyway.
*
* First, we want match the specification as closely as possible. Second we
* need the tag as an index to select the corresponding class name from the
* `CONSTANT_NAMES' array.
*/
protected byte tag;
public int hashCode( Object o ) { Constant(byte tag) {
Constant THIS = (Constant) o; this.tag = tag;
return THIS.toString().hashCode(); }
}
};
/* In fact this tag is redundant since we can distinguish different
* `Constant' objects by their type, i.e., via `instanceof'. In some
* places we will use the tag for switch()es anyway.
*
* First, we want match the specification as closely as possible. Second we
* need the tag as an index to select the corresponding class name from the
* `CONSTANT_NAMES' array.
*/
protected byte tag;
/**
* Called by objects that are traversing the nodes of the tree implicitely
* defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v
* Visitor object
*/
@Override
public abstract void accept(Visitor v);
Constant(byte tag) { public abstract void dump(DataOutputStream file) throws IOException;
this.tag = tag;
}
/**
* @return Tag of constant, i.e., its type. No setTag() method to avoid
* confusion.
*/
public final byte getTag() {
return tag;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public String toString() {
* @param v Visitor object return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]";
*/ }
public abstract void accept( Visitor v );
/**
* @return deep copy of this constant
*/
public Constant copy() {
try {
return (Constant) super.clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
public abstract void dump( DataOutputStream file ) throws IOException; @Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* Read one constant from the given file, the type depends on a tag byte.
*
* @param file
* Input stream
* @return Constant object
*/
static final Constant readConstant(DataInputStream file)
throws IOException, ClassFormatException {
byte b = file.readByte(); // Read tag byte
switch (b) {
case Constants.CONSTANT_Class:
return new ConstantClass(file);
case Constants.CONSTANT_Fieldref:
return new ConstantFieldref(file);
case Constants.CONSTANT_Methodref:
return new ConstantMethodref(file);
case Constants.CONSTANT_InterfaceMethodref:
return new ConstantInterfaceMethodref(file);
case Constants.CONSTANT_String:
return new ConstantString(file);
case Constants.CONSTANT_Integer:
return new ConstantInteger(file);
case Constants.CONSTANT_Float:
return new ConstantFloat(file);
case Constants.CONSTANT_Long:
return new ConstantLong(file);
case Constants.CONSTANT_Double:
return new ConstantDouble(file);
case Constants.CONSTANT_NameAndType:
return new ConstantNameAndType(file);
case Constants.CONSTANT_Utf8:
return new ConstantUtf8(file);
default:
throw new ClassFormatException(
"Invalid byte tag in constant pool: " + b);
}
}
/** /**
* @return Tag of constant, i.e., its type. No setTag() method to avoid * @return Comparison strategy object
* confusion. */
*/ public static BCELComparator getComparator() {
public final byte getTag() { return _cmp;
return tag; }
}
/**
* @param comparator
* Comparison strategy object
*/
public static void setComparator(BCELComparator comparator) {
_cmp = comparator;
}
/** /**
* @return String representation. * Return value as defined by given BCELComparator strategy. By default two
*/ * Constant objects are said to be equal when the result of toString() is
public String toString() { * equal.
return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]"; *
} * @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return _cmp.equals(this, obj);
}
/**
/** * Return value as defined by given BCELComparator strategy. By default
* @return deep copy of this constant * return the hashcode of the result of toString().
*/ *
public Constant copy() { * @see java.lang.Object#hashCode()
try { */
return (Constant) super.clone(); @Override
} catch (CloneNotSupportedException e) { public int hashCode() {
} return _cmp.hashCode(this);
return null; }
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* Read one constant from the given file, the type depends on a tag byte.
*
* @param file Input stream
* @return Constant object
*/
static final Constant readConstant( DataInputStream file ) throws IOException,
ClassFormatException {
byte b = file.readByte(); // Read tag byte
switch (b) {
case Constants.CONSTANT_Class:
return new ConstantClass(file);
case Constants.CONSTANT_Fieldref:
return new ConstantFieldref(file);
case Constants.CONSTANT_Methodref:
return new ConstantMethodref(file);
case Constants.CONSTANT_InterfaceMethodref:
return new ConstantInterfaceMethodref(file);
case Constants.CONSTANT_String:
return new ConstantString(file);
case Constants.CONSTANT_Integer:
return new ConstantInteger(file);
case Constants.CONSTANT_Float:
return new ConstantFloat(file);
case Constants.CONSTANT_Long:
return new ConstantLong(file);
case Constants.CONSTANT_Double:
return new ConstantDouble(file);
case Constants.CONSTANT_NameAndType:
return new ConstantNameAndType(file);
case Constants.CONSTANT_Utf8:
return new ConstantUtf8(file);
default:
throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
}
}
/**
* @return Comparison strategy object
*/
public static BCELComparator getComparator() {
return _cmp;
}
/**
* @param comparator Comparison strategy object
*/
public static void setComparator( BCELComparator comparator ) {
_cmp = comparator;
}
/**
* Return value as defined by given BCELComparator strategy.
* By default two Constant objects are said to be equal when
* the result of toString() is equal.
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals( Object obj ) {
return _cmp.equals(this, obj);
}
/**
* Return value as defined by given BCELComparator strategy.
* By default return the hashcode of the result of toString().
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return _cmp.hashCode(this);
}
} }

View File

@ -21,111 +21,115 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* Abstract super class for Fieldref and Methodref constants. * Abstract super class for Fieldref and Methodref constants.
* *
* @version $Id: ConstantCP.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantCP.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see ConstantFieldref * @see ConstantFieldref
* @see ConstantMethodref * @see ConstantMethodref
* @see ConstantInterfaceMethodref * @see ConstantInterfaceMethodref
*/ */
public abstract class ConstantCP extends Constant { public abstract class ConstantCP extends Constant {
/** References to the constants containing the class and the field signature /**
*/ *
protected int class_index, name_and_type_index; */
private static final long serialVersionUID = 1L;
/**
* References to the constants containing the class and the field signature
*/
protected int class_index, name_and_type_index;
/**
* Initialize from another object.
*/
public ConstantCP(ConstantCP c) {
this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex());
}
/** /**
* Initialize from another object. * Initialize instance from file data.
*/ *
public ConstantCP(ConstantCP c) { * @param tag
this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex()); * Constant type tag
} * @param file
* Input stream
* @throws IOException
*/
ConstantCP(byte tag, DataInputStream file) throws IOException {
this(tag, file.readUnsignedShort(), file.readUnsignedShort());
}
/**
* @param class_index
* Reference to the class containing the field
* @param name_and_type_index
* and the field signature
*/
protected ConstantCP(byte tag, int class_index, int name_and_type_index) {
super(tag);
this.class_index = class_index;
this.name_and_type_index = name_and_type_index;
}
/** /**
* Initialize instance from file data. * Dump constant field reference to file stream in binary format.
* *
* @param tag Constant type tag * @param file
* @param file Input stream * Output file stream
* @throws IOException * @throws IOException
*/ */
ConstantCP(byte tag, DataInputStream file) throws IOException { @Override
this(tag, file.readUnsignedShort(), file.readUnsignedShort()); public final void dump(DataOutputStream file) throws IOException {
} file.writeByte(tag);
file.writeShort(class_index);
file.writeShort(name_and_type_index);
}
/**
* @return Reference (index) to class this field or method belongs to.
*/
public final int getClassIndex() {
return class_index;
}
/** /**
* @param class_index Reference to the class containing the field * @return Reference (index) to signature of the field.
* @param name_and_type_index and the field signature */
*/ public final int getNameAndTypeIndex() {
protected ConstantCP(byte tag, int class_index, int name_and_type_index) { return name_and_type_index;
super(tag); }
this.class_index = class_index;
this.name_and_type_index = name_and_type_index;
}
/**
* @param class_index
* points to Constant_class
*/
public final void setClassIndex(int class_index) {
this.class_index = class_index;
}
/** /**
* Dump constant field reference to file stream in binary format. * @return Class this field belongs to.
* */
* @param file Output file stream public String getClass(ConstantPool cp) {
* @throws IOException return cp.constantToString(class_index, Constants.CONSTANT_Class);
*/ }
public final void dump( DataOutputStream file ) throws IOException {
file.writeByte(tag);
file.writeShort(class_index);
file.writeShort(name_and_type_index);
}
/**
* @param name_and_type_index
* points to Constant_NameAndType
*/
public final void setNameAndTypeIndex(int name_and_type_index) {
this.name_and_type_index = name_and_type_index;
}
/** /**
* @return Reference (index) to class this field or method belongs to. * @return String representation.
*/ */
public final int getClassIndex() { @Override
return class_index; public final String toString() {
} return super.toString() + "(class_index = " + class_index
+ ", name_and_type_index = " + name_and_type_index + ")";
}
/**
* @return Reference (index) to signature of the field.
*/
public final int getNameAndTypeIndex() {
return name_and_type_index;
}
/**
* @param class_index points to Constant_class
*/
public final void setClassIndex( int class_index ) {
this.class_index = class_index;
}
/**
* @return Class this field belongs to.
*/
public String getClass( ConstantPool cp ) {
return cp.constantToString(class_index, Constants.CONSTANT_Class);
}
/**
* @param name_and_type_index points to Constant_NameAndType
*/
public final void setNameAndTypeIndex( int name_and_type_index ) {
this.name_and_type_index = name_and_type_index;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(class_index = " + class_index + ", name_and_type_index = "
+ name_and_type_index + ")";
}
} }

View File

@ -21,108 +21,112 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from the abstract * This class is derived from the abstract <A
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class * HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* and represents a reference to a (external) class. * represents a reference to a (external) class.
* *
* @version $Id: ConstantClass.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantClass.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public final class ConstantClass extends Constant implements ConstantObject { public final class ConstantClass extends Constant implements ConstantObject {
private int name_index; // Identical to ConstantString except for the name /**
*
*/
private static final long serialVersionUID = 1L;
private int name_index; // Identical to ConstantString except for the name
/**
* Initialize from another object.
*/
public ConstantClass(ConstantClass c) {
this(c.getNameIndex());
}
/** /**
* Initialize from another object. * Initialize instance from file data.
*/ *
public ConstantClass(ConstantClass c) { * @param file
this(c.getNameIndex()); * Input stream
} * @throws IOException
*/
ConstantClass(DataInputStream file) throws IOException {
this(file.readUnsignedShort());
}
/**
* @param name_index
* Name index in constant pool. Should refer to a ConstantUtf8.
*/
public ConstantClass(int name_index) {
super(Constants.CONSTANT_Class);
this.name_index = name_index;
}
/** /**
* Initialize instance from file data. * Called by objects that are traversing the nodes of the tree implicitely
* * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param file Input stream * fields, attributes, etc. spawns a tree of objects.
* @throws IOException *
*/ * @param v
ConstantClass(DataInputStream file) throws IOException { * Visitor object
this(file.readUnsignedShort()); */
} @Override
public void accept(Visitor v) {
v.visitConstantClass(this);
}
/**
* Dump constant class to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeShort(name_index);
}
/** /**
* @param name_index Name index in constant pool. Should refer to a * @return Name index in constant pool of class name.
* ConstantUtf8. */
*/ public final int getNameIndex() {
public ConstantClass(int name_index) { return name_index;
super(Constants.CONSTANT_Class); }
this.name_index = name_index;
}
/**
* @param name_index
* the name index in the constant pool of this Constant Class
*/
public final void setNameIndex(int name_index) {
this.name_index = name_index;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String object
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public Object getConstantValue(ConstantPool cp) {
* @param v Visitor object Constant c = cp.getConstant(name_index, Constants.CONSTANT_Utf8);
*/ return ((ConstantUtf8) c).getBytes();
public void accept( Visitor v ) { }
v.visitConstantClass(this);
}
/**
* @return dereferenced string
*/
public String getBytes(ConstantPool cp) {
return (String) getConstantValue(cp);
}
/** /**
* Dump constant class to file stream in binary format. * @return String representation.
* */
* @param file Output file stream @Override
* @throws IOException public final String toString() {
*/ return super.toString() + "(name_index = " + name_index + ")";
public final void dump( DataOutputStream file ) throws IOException { }
file.writeByte(tag);
file.writeShort(name_index);
}
/**
* @return Name index in constant pool of class name.
*/
public final int getNameIndex() {
return name_index;
}
/**
* @param name_index the name index in the constant pool of this Constant Class
*/
public final void setNameIndex( int name_index ) {
this.name_index = name_index;
}
/** @return String object
*/
public Object getConstantValue( ConstantPool cp ) {
Constant c = cp.getConstant(name_index, Constants.CONSTANT_Utf8);
return ((ConstantUtf8) c).getBytes();
}
/** @return dereferenced string
*/
public String getBytes( ConstantPool cp ) {
return (String) getConstantValue(cp);
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(name_index = " + name_index + ")";
}
} }

View File

@ -21,99 +21,104 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from the abstract * This class is derived from the abstract <A
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class * HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* and represents a reference to a Double object. * represents a reference to a Double object.
* *
* @version $Id: ConstantDouble.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantDouble.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public final class ConstantDouble extends Constant implements ConstantObject { public final class ConstantDouble extends Constant implements ConstantObject {
private double bytes; /**
*
*/
private static final long serialVersionUID = 1L;
private double bytes;
/**
* @param bytes
* Data
*/
public ConstantDouble(double bytes) {
super(Constants.CONSTANT_Double);
this.bytes = bytes;
}
/** /**
* @param bytes Data * Initialize from another object.
*/ */
public ConstantDouble(double bytes) { public ConstantDouble(ConstantDouble c) {
super(Constants.CONSTANT_Double); this(c.getBytes());
this.bytes = bytes; }
}
/**
* Initialize instance from file data.
*
* @param file
* Input stream
* @throws IOException
*/
ConstantDouble(DataInputStream file) throws IOException {
this(file.readDouble());
}
/** /**
* Initialize from another object. * Called by objects that are traversing the nodes of the tree implicitely
*/ * defined by the contents of a Java class. I.e., the hierarchy of methods,
public ConstantDouble(ConstantDouble c) { * fields, attributes, etc. spawns a tree of objects.
this(c.getBytes()); *
} * @param v
* Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitConstantDouble(this);
}
/**
* Dump constant double to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeDouble(bytes);
}
/** /**
* Initialize instance from file data. * @return data, i.e., 8 bytes.
* */
* @param file Input stream public final double getBytes() {
* @throws IOException return bytes;
*/ }
ConstantDouble(DataInputStream file) throws IOException {
this(file.readDouble());
}
/**
* @param bytes
* the raw bytes that represent the double value
*/
public final void setBytes(double bytes) {
this.bytes = bytes;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object return super.toString() + "(bytes = " + bytes + ")";
*/ }
public void accept( Visitor v ) {
v.visitConstantDouble(this);
}
/**
/** * @return Double object
* Dump constant double to file stream in binary format. */
* @Override
* @param file Output file stream public Object getConstantValue(ConstantPool cp) {
* @throws IOException return new Double(bytes);
*/ }
public final void dump( DataOutputStream file ) throws IOException {
file.writeByte(tag);
file.writeDouble(bytes);
}
/**
* @return data, i.e., 8 bytes.
*/
public final double getBytes() {
return bytes;
}
/**
* @param bytes the raw bytes that represent the double value
*/
public final void setBytes( double bytes ) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
/** @return Double object
*/
public Object getConstantValue( ConstantPool cp ) {
return new Double(bytes);
}
} }

View File

@ -20,50 +20,58 @@ import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents a constant pool reference to a field. * This class represents a constant pool reference to a field.
* *
* @version $Id: ConstantFieldref.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantFieldref.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class ConstantFieldref extends ConstantCP { public final class ConstantFieldref extends ConstantCP {
/** /**
* Initialize from another object. *
*/ */
public ConstantFieldref(ConstantFieldref c) { private static final long serialVersionUID = 1L;
super(Constants.CONSTANT_Fieldref, c.getClassIndex(), c.getNameAndTypeIndex());
}
/**
* Initialize from another object.
*/
public ConstantFieldref(ConstantFieldref c) {
super(Constants.CONSTANT_Fieldref, c.getClassIndex(), c
.getNameAndTypeIndex());
}
/** /**
* Initialize instance from file data. * Initialize instance from file data.
* *
* @param file input stream * @param file
* @throws IOException * input stream
*/ * @throws IOException
ConstantFieldref(DataInputStream file) throws IOException { */
super(Constants.CONSTANT_Fieldref, file); ConstantFieldref(DataInputStream file) throws IOException {
} super(Constants.CONSTANT_Fieldref, file);
}
/**
* @param class_index
* Reference to the class containing the Field
* @param name_and_type_index
* and the Field signature
*/
public ConstantFieldref(int class_index, int name_and_type_index) {
super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index);
}
/** /**
* @param class_index Reference to the class containing the Field * Called by objects that are traversing the nodes of the tree implicitely
* @param name_and_type_index and the Field signature * defined by the contents of a Java class. I.e., the hierarchy of Fields,
*/ * fields, attributes, etc. spawns a tree of objects.
public ConstantFieldref(int class_index, int name_and_type_index) { *
super(Constants.CONSTANT_Fieldref, class_index, name_and_type_index); * @param v
} * Visitor object
*/
@Override
/** public void accept(Visitor v) {
* Called by objects that are traversing the nodes of the tree implicitely v.visitConstantFieldref(this);
* defined by the contents of a Java class. I.e., the hierarchy of Fields, }
* fields, attributes, etc. spawns a tree of objects.
*
* @param v Visitor object
*/
public void accept( Visitor v ) {
v.visitConstantFieldref(this);
}
} }

View File

@ -21,100 +21,105 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from the abstract * This class is derived from the abstract <A
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class * HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* and represents a reference to a float object. * represents a reference to a float object.
* *
* @version $Id: ConstantFloat.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantFloat.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public final class ConstantFloat extends Constant implements ConstantObject { public final class ConstantFloat extends Constant implements ConstantObject {
private float bytes; /**
*
*/
private static final long serialVersionUID = 1L;
private float bytes;
/**
* @param bytes
* Data
*/
public ConstantFloat(float bytes) {
super(Constants.CONSTANT_Float);
this.bytes = bytes;
}
/** /**
* @param bytes Data * Initialize from another object. Note that both objects use the same
*/ * references (shallow copy). Use clone() for a physical copy.
public ConstantFloat(float bytes) { */
super(Constants.CONSTANT_Float); public ConstantFloat(ConstantFloat c) {
this.bytes = bytes; this(c.getBytes());
} }
/**
* Initialize instance from file data.
*
* @param file
* Input stream
* @throws IOException
*/
ConstantFloat(DataInputStream file) throws IOException {
this(file.readFloat());
}
/** /**
* Initialize from another object. Note that both objects use the same * Called by objects that are traversing the nodes of the tree implicitely
* references (shallow copy). Use clone() for a physical copy. * defined by the contents of a Java class. I.e., the hierarchy of methods,
*/ * fields, attributes, etc. spawns a tree of objects.
public ConstantFloat(ConstantFloat c) { *
this(c.getBytes()); * @param v
} * Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitConstantFloat(this);
}
/**
* Dump constant float to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeFloat(bytes);
}
/** /**
* Initialize instance from file data. * @return data, i.e., 4 bytes.
* */
* @param file Input stream public final float getBytes() {
* @throws IOException return bytes;
*/ }
ConstantFloat(DataInputStream file) throws IOException {
this(file.readFloat());
}
/**
* @param bytes
* the raw bytes that represent this float
*/
public final void setBytes(float bytes) {
this.bytes = bytes;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object return super.toString() + "(bytes = " + bytes + ")";
*/ }
public void accept( Visitor v ) {
v.visitConstantFloat(this);
}
/**
/** * @return Float object
* Dump constant float to file stream in binary format. */
* @Override
* @param file Output file stream public Object getConstantValue(ConstantPool cp) {
* @throws IOException return new Float(bytes);
*/ }
public final void dump( DataOutputStream file ) throws IOException {
file.writeByte(tag);
file.writeFloat(bytes);
}
/**
* @return data, i.e., 4 bytes.
*/
public final float getBytes() {
return bytes;
}
/**
* @param bytes the raw bytes that represent this float
*/
public final void setBytes( float bytes ) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
/** @return Float object
*/
public Object getConstantValue( ConstantPool cp ) {
return new Float(bytes);
}
} }

View File

@ -21,99 +21,104 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from the abstract * This class is derived from the abstract <A
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class * HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* and represents a reference to an int object. * represents a reference to an int object.
* *
* @version $Id: ConstantInteger.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantInteger.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public final class ConstantInteger extends Constant implements ConstantObject { public final class ConstantInteger extends Constant implements ConstantObject {
private int bytes; /**
*
*/
private static final long serialVersionUID = 1L;
private int bytes;
/**
* @param bytes
* Data
*/
public ConstantInteger(int bytes) {
super(Constants.CONSTANT_Integer);
this.bytes = bytes;
}
/** /**
* @param bytes Data * Initialize from another object.
*/ */
public ConstantInteger(int bytes) { public ConstantInteger(ConstantInteger c) {
super(Constants.CONSTANT_Integer); this(c.getBytes());
this.bytes = bytes; }
}
/**
* Initialize instance from file data.
*
* @param file
* Input stream
* @throws IOException
*/
ConstantInteger(DataInputStream file) throws IOException {
this(file.readInt());
}
/** /**
* Initialize from another object. * Called by objects that are traversing the nodes of the tree implicitely
*/ * defined by the contents of a Java class. I.e., the hierarchy of methods,
public ConstantInteger(ConstantInteger c) { * fields, attributes, etc. spawns a tree of objects.
this(c.getBytes()); *
} * @param v
* Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitConstantInteger(this);
}
/**
* Dump constant integer to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeInt(bytes);
}
/** /**
* Initialize instance from file data. * @return data, i.e., 4 bytes.
* */
* @param file Input stream public final int getBytes() {
* @throws IOException return bytes;
*/ }
ConstantInteger(DataInputStream file) throws IOException {
this(file.readInt());
}
/**
* @param bytes
* the raw bytes that represent this integer
*/
public final void setBytes(int bytes) {
this.bytes = bytes;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object return super.toString() + "(bytes = " + bytes + ")";
*/ }
public void accept( Visitor v ) {
v.visitConstantInteger(this);
}
/**
/** * @return Integer object
* Dump constant integer to file stream in binary format. */
* @Override
* @param file Output file stream public Object getConstantValue(ConstantPool cp) {
* @throws IOException return new Integer(bytes);
*/ }
public final void dump( DataOutputStream file ) throws IOException {
file.writeByte(tag);
file.writeInt(bytes);
}
/**
* @return data, i.e., 4 bytes.
*/
public final int getBytes() {
return bytes;
}
/**
* @param bytes the raw bytes that represent this integer
*/
public final void setBytes( int bytes ) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
/** @return Integer object
*/
public Object getConstantValue( ConstantPool cp ) {
return new Integer(bytes);
}
} }

View File

@ -20,50 +20,60 @@ import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents a constant pool reference to an interface method. * This class represents a constant pool reference to an interface method.
* *
* @version $Id: ConstantInterfaceMethodref.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantInterfaceMethodref.java 386056 2006-03-15 11:31:56Z
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class ConstantInterfaceMethodref extends ConstantCP { public final class ConstantInterfaceMethodref extends ConstantCP {
/** /**
* Initialize from another object. *
*/ */
public ConstantInterfaceMethodref(ConstantInterfaceMethodref c) { private static final long serialVersionUID = 1L;
super(Constants.CONSTANT_InterfaceMethodref, c.getClassIndex(), c.getNameAndTypeIndex());
}
/**
* Initialize from another object.
*/
public ConstantInterfaceMethodref(ConstantInterfaceMethodref c) {
super(Constants.CONSTANT_InterfaceMethodref, c.getClassIndex(), c
.getNameAndTypeIndex());
}
/** /**
* Initialize instance from file data. * Initialize instance from file data.
* *
* @param file input stream * @param file
* @throws IOException * input stream
*/ * @throws IOException
ConstantInterfaceMethodref(DataInputStream file) throws IOException { */
super(Constants.CONSTANT_InterfaceMethodref, file); ConstantInterfaceMethodref(DataInputStream file) throws IOException {
} super(Constants.CONSTANT_InterfaceMethodref, file);
}
/**
* @param class_index
* Reference to the class containing the method
* @param name_and_type_index
* and the method signature
*/
public ConstantInterfaceMethodref(int class_index, int name_and_type_index) {
super(Constants.CONSTANT_InterfaceMethodref, class_index,
name_and_type_index);
}
/** /**
* @param class_index Reference to the class containing the method * Called by objects that are traversing the nodes of the tree implicitely
* @param name_and_type_index and the method signature * defined by the contents of a Java class. I.e., the hierarchy of methods,
*/ * fields, attributes, etc. spawns a tree of objects.
public ConstantInterfaceMethodref(int class_index, int name_and_type_index) { *
super(Constants.CONSTANT_InterfaceMethodref, class_index, name_and_type_index); * @param v
} * Visitor object
*/
@Override
/** public void accept(Visitor v) {
* Called by objects that are traversing the nodes of the tree implicitely v.visitConstantInterfaceMethodref(this);
* defined by the contents of a Java class. I.e., the hierarchy of methods, }
* fields, attributes, etc. spawns a tree of objects.
*
* @param v Visitor object
*/
public void accept( Visitor v ) {
v.visitConstantInterfaceMethodref(this);
}
} }

View File

@ -21,99 +21,104 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from the abstract * This class is derived from the abstract <A
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class * HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* and represents a reference to a long object. * represents a reference to a long object.
* *
* @version $Id: ConstantLong.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantLong.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public final class ConstantLong extends Constant implements ConstantObject { public final class ConstantLong extends Constant implements ConstantObject {
private long bytes; /**
*
*/
private static final long serialVersionUID = 1L;
private long bytes;
/**
* @param bytes
* Data
*/
public ConstantLong(long bytes) {
super(Constants.CONSTANT_Long);
this.bytes = bytes;
}
/** /**
* @param bytes Data * Initialize from another object.
*/ */
public ConstantLong(long bytes) { public ConstantLong(ConstantLong c) {
super(Constants.CONSTANT_Long); this(c.getBytes());
this.bytes = bytes; }
}
/**
* Initialize instance from file data.
*
* @param file
* Input stream
* @throws IOException
*/
ConstantLong(DataInputStream file) throws IOException {
this(file.readLong());
}
/** /**
* Initialize from another object. * Called by objects that are traversing the nodes of the tree implicitely
*/ * defined by the contents of a Java class. I.e., the hierarchy of methods,
public ConstantLong(ConstantLong c) { * fields, attributes, etc. spawns a tree of objects.
this(c.getBytes()); *
} * @param v
* Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitConstantLong(this);
}
/**
* Dump constant long to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeLong(bytes);
}
/** /**
* Initialize instance from file data. * @return data, i.e., 8 bytes.
* */
* @param file Input stream public final long getBytes() {
* @throws IOException return bytes;
*/ }
ConstantLong(DataInputStream file) throws IOException {
this(file.readLong());
}
/**
* @param bytes
* thr raw bytes that represent this long
*/
public final void setBytes(long bytes) {
this.bytes = bytes;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object return super.toString() + "(bytes = " + bytes + ")";
*/ }
public void accept( Visitor v ) {
v.visitConstantLong(this);
}
/**
/** * @return Long object
* Dump constant long to file stream in binary format. */
* @Override
* @param file Output file stream public Object getConstantValue(ConstantPool cp) {
* @throws IOException return new Long(bytes);
*/ }
public final void dump( DataOutputStream file ) throws IOException {
file.writeByte(tag);
file.writeLong(bytes);
}
/**
* @return data, i.e., 8 bytes.
*/
public final long getBytes() {
return bytes;
}
/**
* @param bytes thr raw bytes that represent this long
*/
public final void setBytes( long bytes ) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
/** @return Long object
*/
public Object getConstantValue( ConstantPool cp ) {
return new Long(bytes);
}
} }

View File

@ -20,50 +20,58 @@ import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents a constant pool reference to a method. * This class represents a constant pool reference to a method.
* *
* @version $Id: ConstantMethodref.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantMethodref.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class ConstantMethodref extends ConstantCP { public final class ConstantMethodref extends ConstantCP {
/** /**
* Initialize from another object. *
*/ */
public ConstantMethodref(ConstantMethodref c) { private static final long serialVersionUID = 1L;
super(Constants.CONSTANT_Methodref, c.getClassIndex(), c.getNameAndTypeIndex());
}
/**
* Initialize from another object.
*/
public ConstantMethodref(ConstantMethodref c) {
super(Constants.CONSTANT_Methodref, c.getClassIndex(), c
.getNameAndTypeIndex());
}
/** /**
* Initialize instance from file data. * Initialize instance from file data.
* *
* @param file input stream * @param file
* @throws IOException * input stream
*/ * @throws IOException
ConstantMethodref(DataInputStream file) throws IOException { */
super(Constants.CONSTANT_Methodref, file); ConstantMethodref(DataInputStream file) throws IOException {
} super(Constants.CONSTANT_Methodref, file);
}
/**
* @param class_index
* Reference to the class containing the method
* @param name_and_type_index
* and the method signature
*/
public ConstantMethodref(int class_index, int name_and_type_index) {
super(Constants.CONSTANT_Methodref, class_index, name_and_type_index);
}
/** /**
* @param class_index Reference to the class containing the method * Called by objects that are traversing the nodes of the tree implicitely
* @param name_and_type_index and the method signature * defined by the contents of a Java class. I.e., the hierarchy of methods,
*/ * fields, attributes, etc. spawns a tree of objects.
public ConstantMethodref(int class_index, int name_and_type_index) { *
super(Constants.CONSTANT_Methodref, class_index, name_and_type_index); * @param v
} * Visitor object
*/
@Override
/** public void accept(Visitor v) {
* Called by objects that are traversing the nodes of the tree implicitely v.visitConstantMethodref(this);
* defined by the contents of a Java class. I.e., the hierarchy of methods, }
* fields, attributes, etc. spawns a tree of objects.
*
* @param v Visitor object
*/
public void accept( Visitor v ) {
v.visitConstantMethodref(this);
}
} }

View File

@ -21,128 +21,132 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from the abstract * This class is derived from the abstract <A
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class * HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* and represents a reference to the name and signature * represents a reference to the name and signature of a field or method.
* of a field or method. *
*
* @version $Id: ConstantNameAndType.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantNameAndType.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public final class ConstantNameAndType extends Constant { public final class ConstantNameAndType extends Constant {
private int name_index; // Name of field/method /**
private int signature_index; // and its signature. *
*/
private static final long serialVersionUID = 1L;
private int name_index; // Name of field/method
private int signature_index; // and its signature.
/**
* Initialize from another object.
*/
public ConstantNameAndType(ConstantNameAndType c) {
this(c.getNameIndex(), c.getSignatureIndex());
}
/** /**
* Initialize from another object. * Initialize instance from file data.
*/ *
public ConstantNameAndType(ConstantNameAndType c) { * @param file
this(c.getNameIndex(), c.getSignatureIndex()); * Input stream
} * @throws IOException
*/
ConstantNameAndType(DataInputStream file) throws IOException {
this(file.readUnsignedShort(), file.readUnsignedShort());
}
/**
* @param name_index
* Name of field/method
* @param signature_index
* and its signature
*/
public ConstantNameAndType(int name_index, int signature_index) {
super(Constants.CONSTANT_NameAndType);
this.name_index = name_index;
this.signature_index = signature_index;
}
/** /**
* Initialize instance from file data. * Called by objects that are traversing the nodes of the tree implicitely
* * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param file Input stream * fields, attributes, etc. spawns a tree of objects.
* @throws IOException *
*/ * @param v
ConstantNameAndType(DataInputStream file) throws IOException { * Visitor object
this(file.readUnsignedShort(), file.readUnsignedShort()); */
} @Override
public void accept(Visitor v) {
v.visitConstantNameAndType(this);
}
/**
* Dump name and signature index to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeShort(name_index);
file.writeShort(signature_index);
}
/** /**
* @param name_index Name of field/method * @return Name index in constant pool of field/method name.
* @param signature_index and its signature */
*/ public final int getNameIndex() {
public ConstantNameAndType(int name_index, int signature_index) { return name_index;
super(Constants.CONSTANT_NameAndType); }
this.name_index = name_index;
this.signature_index = signature_index;
}
/**
* @return name
*/
public final String getName(ConstantPool cp) {
return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8);
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return Index in constant pool of field/method signature.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final int getSignatureIndex() {
* return signature_index;
* @param v Visitor object }
*/
public void accept( Visitor v ) {
v.visitConstantNameAndType(this);
}
/**
* @return signature
*/
public final String getSignature(ConstantPool cp) {
return cp
.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8);
}
/** /**
* Dump name and signature index to file stream in binary format. * @param name_index
* * the name index of this constant
* @param file Output file stream */
* @throws IOException public final void setNameIndex(int name_index) {
*/ this.name_index = name_index;
public final void dump( DataOutputStream file ) throws IOException { }
file.writeByte(tag);
file.writeShort(name_index);
file.writeShort(signature_index);
}
/**
* @param signature_index
* the signature index in the constant pool of this type
*/
public final void setSignatureIndex(int signature_index) {
this.signature_index = signature_index;
}
/** /**
* @return Name index in constant pool of field/method name. * @return String representation
*/ */
public final int getNameIndex() { @Override
return name_index; public final String toString() {
} return super.toString() + "(name_index = " + name_index
+ ", signature_index = " + signature_index + ")";
}
/** @return name
*/
public final String getName( ConstantPool cp ) {
return cp.constantToString(getNameIndex(), Constants.CONSTANT_Utf8);
}
/**
* @return Index in constant pool of field/method signature.
*/
public final int getSignatureIndex() {
return signature_index;
}
/** @return signature
*/
public final String getSignature( ConstantPool cp ) {
return cp.constantToString(getSignatureIndex(), Constants.CONSTANT_Utf8);
}
/**
* @param name_index the name index of this constant
*/
public final void setNameIndex( int name_index ) {
this.name_index = name_index;
}
/**
* @param signature_index the signature index in the constant pool of this type
*/
public final void setSignatureIndex( int signature_index ) {
this.signature_index = signature_index;
}
/**
* @return String representation
*/
public final String toString() {
return super.toString() + "(name_index = " + name_index + ", signature_index = "
+ signature_index + ")";
}
} }

View File

@ -16,17 +16,18 @@
*/ */
package org.apache.bcel.classfile; package org.apache.bcel.classfile;
/** /**
* This interface denotes those constants that have a "natural" value, * This interface denotes those constants that have a "natural" value, such as
* such as ConstantLong, ConstantString, etc.. * ConstantLong, ConstantString, etc..
* *
* @version $Id: ConstantObject.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantObject.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public interface ConstantObject { public interface ConstantObject {
/** @return object representing the constant, e.g., Long for ConstantLong /**
*/ * @return object representing the constant, e.g., Long for ConstantLong
public abstract Object getConstantValue( ConstantPool cp ); */
public abstract Object getConstantValue(ConstantPool cp);
} }

View File

@ -23,331 +23,346 @@ import java.io.Serializable;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents the constant pool, i.e., a table of constants, of * This class represents the constant pool, i.e., a table of constants, of a
* a parsed classfile. It may contain null references, due to the JVM * parsed classfile. It may contain null references, due to the JVM
* specification that skips an entry after an 8-byte constant (double, * specification that skips an entry after an 8-byte constant (double, long)
* long) entry. Those interested in generating constant pools * entry. Those interested in generating constant pools programatically should
* programatically should see <a href="../generic/ConstantPoolGen.html"> * see <a href="../generic/ConstantPoolGen.html"> ConstantPoolGen</a>.
* ConstantPoolGen</a>. *
* @version $Id: ConstantPool.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantPool.java 386056 2006-03-15 11:31:56Z tcurdt $
* @see Constant * @see Constant
* @see org.apache.bcel.generic.ConstantPoolGen * @see org.apache.bcel.generic.ConstantPoolGen
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ConstantPool implements Cloneable, Node, Serializable { public class ConstantPool implements Cloneable, Node, Serializable {
private int constant_pool_count; /**
private Constant[] constant_pool; *
*/
private static final long serialVersionUID = 1L;
private int constant_pool_count;
private Constant[] constant_pool;
/**
* @param constant_pool
* Array of constants
*/
public ConstantPool(Constant[] constant_pool) {
setConstantPool(constant_pool);
}
/** /**
* @param constant_pool Array of constants * Read constants from given file stream.
*/ *
public ConstantPool(Constant[] constant_pool) { * @param file
setConstantPool(constant_pool); * Input stream
} * @throws IOException
* @throws ClassFormatException
*/
ConstantPool(DataInputStream file) throws IOException, ClassFormatException {
byte tag;
constant_pool_count = file.readUnsignedShort();
constant_pool = new Constant[constant_pool_count];
/*
* constant_pool[0] is unused by the compiler and may be used freely by
* the implementation.
*/
for (int i = 1; i < constant_pool_count; i++) {
constant_pool[i] = Constant.readConstant(file);
/*
* Quote from the JVM specification: "All eight byte constants take
* up two spots in the constant pool. If this is the n'th byte in
* the constant pool, then the next item will be numbered n+2"
*
* Thus we have to increment the index counter.
*/
tag = constant_pool[i].getTag();
if ((tag == Constants.CONSTANT_Double)
|| (tag == Constants.CONSTANT_Long)) {
i++;
}
}
}
/**
* Called by objects that are traversing the nodes of the tree implicitely
* defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v
* Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitConstantPool(this);
}
/** /**
* Read constants from given file stream. * Resolve constant to a string representation.
* *
* @param file Input stream * @param c
* @throws IOException * Constant to be printed
* @throws ClassFormatException * @return String representation
*/ */
ConstantPool(DataInputStream file) throws IOException, ClassFormatException { public String constantToString(Constant c) throws ClassFormatException {
byte tag; String str;
constant_pool_count = file.readUnsignedShort(); int i;
constant_pool = new Constant[constant_pool_count]; byte tag = c.getTag();
/* constant_pool[0] is unused by the compiler and may be used freely switch (tag) {
* by the implementation. case Constants.CONSTANT_Class:
*/ i = ((ConstantClass) c).getNameIndex();
for (int i = 1; i < constant_pool_count; i++) { c = getConstant(i, Constants.CONSTANT_Utf8);
constant_pool[i] = Constant.readConstant(file); str = Utility
/* Quote from the JVM specification: .compactClassName(((ConstantUtf8) c).getBytes(), false);
* "All eight byte constants take up two spots in the constant pool. break;
* If this is the n'th byte in the constant pool, then the next item case Constants.CONSTANT_String:
* will be numbered n+2" i = ((ConstantString) c).getStringIndex();
* c = getConstant(i, Constants.CONSTANT_Utf8);
* Thus we have to increment the index counter. str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\"";
*/ break;
tag = constant_pool[i].getTag(); case Constants.CONSTANT_Utf8:
if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) { str = ((ConstantUtf8) c).getBytes();
i++; break;
} case Constants.CONSTANT_Double:
} str = "" + ((ConstantDouble) c).getBytes();
} break;
case Constants.CONSTANT_Float:
str = "" + ((ConstantFloat) c).getBytes();
break;
case Constants.CONSTANT_Long:
str = "" + ((ConstantLong) c).getBytes();
break;
case Constants.CONSTANT_Integer:
str = "" + ((ConstantInteger) c).getBytes();
break;
case Constants.CONSTANT_NameAndType:
str = (constantToString(((ConstantNameAndType) c).getNameIndex(),
Constants.CONSTANT_Utf8) + " " + constantToString(
((ConstantNameAndType) c).getSignatureIndex(),
Constants.CONSTANT_Utf8));
break;
case Constants.CONSTANT_InterfaceMethodref:
case Constants.CONSTANT_Methodref:
case Constants.CONSTANT_Fieldref:
str = (constantToString(((ConstantCP) c).getClassIndex(),
Constants.CONSTANT_Class) + "." + constantToString(
((ConstantCP) c).getNameAndTypeIndex(),
Constants.CONSTANT_NameAndType));
break;
default: // Never reached
throw new RuntimeException("Unknown constant type " + tag);
}
return str;
}
private static final String escape(String str) {
int len = str.length();
StringBuffer buf = new StringBuffer(len + 5);
char[] ch = str.toCharArray();
for (int i = 0; i < len; i++) {
switch (ch[i]) {
case '\n':
buf.append("\\n");
break;
case '\r':
buf.append("\\r");
break;
case '\t':
buf.append("\\t");
break;
case '\b':
buf.append("\\b");
break;
case '"':
buf.append("\\\"");
break;
default:
buf.append(ch[i]);
}
}
return buf.toString();
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * Retrieve constant at `index' from constant pool and resolve it to a
* defined by the contents of a Java class. I.e., the hierarchy of methods, * string representation.
* fields, attributes, etc. spawns a tree of objects. *
* * @param index
* @param v Visitor object * of constant in constant pool
*/ * @param tag
public void accept( Visitor v ) { * expected type
v.visitConstantPool(this); * @return String representation
} */
public String constantToString(int index, byte tag)
throws ClassFormatException {
Constant c = getConstant(index, tag);
return constantToString(c);
}
/**
* Dump constant pool to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
public void dump(DataOutputStream file) throws IOException {
file.writeShort(constant_pool_count);
for (int i = 1; i < constant_pool_count; i++) {
if (constant_pool[i] != null) {
constant_pool[i].dump(file);
}
}
}
/** /**
* Resolve constant to a string representation. * Get constant from constant pool.
* *
* @param c Constant to be printed * @param index
* @return String representation * Index in constant pool
*/ * @return Constant value
public String constantToString( Constant c ) throws ClassFormatException { * @see Constant
String str; */
int i; public Constant getConstant(int index) {
byte tag = c.getTag(); if (index >= constant_pool.length || index < 0) {
switch (tag) { throw new ClassFormatException("Invalid constant pool reference: "
case Constants.CONSTANT_Class: + index + ". Constant pool size is: "
i = ((ConstantClass) c).getNameIndex(); + constant_pool.length);
c = getConstant(i, Constants.CONSTANT_Utf8); }
str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false); return constant_pool[index];
break; }
case Constants.CONSTANT_String:
i = ((ConstantString) c).getStringIndex();
c = getConstant(i, Constants.CONSTANT_Utf8);
str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\"";
break;
case Constants.CONSTANT_Utf8:
str = ((ConstantUtf8) c).getBytes();
break;
case Constants.CONSTANT_Double:
str = "" + ((ConstantDouble) c).getBytes();
break;
case Constants.CONSTANT_Float:
str = "" + ((ConstantFloat) c).getBytes();
break;
case Constants.CONSTANT_Long:
str = "" + ((ConstantLong) c).getBytes();
break;
case Constants.CONSTANT_Integer:
str = "" + ((ConstantInteger) c).getBytes();
break;
case Constants.CONSTANT_NameAndType:
str = (constantToString(((ConstantNameAndType) c).getNameIndex(),
Constants.CONSTANT_Utf8)
+ " " + constantToString(((ConstantNameAndType) c).getSignatureIndex(),
Constants.CONSTANT_Utf8));
break;
case Constants.CONSTANT_InterfaceMethodref:
case Constants.CONSTANT_Methodref:
case Constants.CONSTANT_Fieldref:
str = (constantToString(((ConstantCP) c).getClassIndex(), Constants.CONSTANT_Class)
+ "." + constantToString(((ConstantCP) c).getNameAndTypeIndex(),
Constants.CONSTANT_NameAndType));
break;
default: // Never reached
throw new RuntimeException("Unknown constant type " + tag);
}
return str;
}
/**
* Get constant from constant pool and check whether it has the expected
* type.
*
* @param index
* Index in constant pool
* @param tag
* Tag of expected constant, i.e., its type
* @return Constant value
* @see Constant
* @throws ClassFormatException
*/
public Constant getConstant(int index, byte tag)
throws ClassFormatException {
Constant c;
c = getConstant(index);
if (c == null) {
throw new ClassFormatException("Constant pool at index " + index
+ " is null.");
}
if (c.getTag() != tag) {
throw new ClassFormatException("Expected class `"
+ Constants.CONSTANT_NAMES[tag] + "' at index " + index
+ " and got " + c);
}
return c;
}
private static final String escape( String str ) { /**
int len = str.length(); * @return Array of constants.
StringBuffer buf = new StringBuffer(len + 5); * @see Constant
char[] ch = str.toCharArray(); */
for (int i = 0; i < len; i++) { public Constant[] getConstantPool() {
switch (ch[i]) { return constant_pool;
case '\n': }
buf.append("\\n");
break;
case '\r':
buf.append("\\r");
break;
case '\t':
buf.append("\\t");
break;
case '\b':
buf.append("\\b");
break;
case '"':
buf.append("\\\"");
break;
default:
buf.append(ch[i]);
}
}
return buf.toString();
}
/**
* Get string from constant pool and bypass the indirection of
* `ConstantClass' and `ConstantString' objects. I.e. these classes have an
* index field that points to another entry of the constant pool of type
* `ConstantUtf8' which contains the real data.
*
* @param index
* Index in constant pool
* @param tag
* Tag of expected constant, either ConstantClass or
* ConstantString
* @return Contents of string reference
* @see ConstantClass
* @see ConstantString
* @throws ClassFormatException
*/
public String getConstantString(int index, byte tag)
throws ClassFormatException {
Constant c;
int i;
c = getConstant(index, tag);
/*
* This switch() is not that elegant, since the two classes have the
* same contents, they just differ in the name of the index field
* variable. But we want to stick to the JVM naming conventions closely
* though we could have solved these more elegantly by using the same
* variable name or by subclassing.
*/
switch (tag) {
case Constants.CONSTANT_Class:
i = ((ConstantClass) c).getNameIndex();
break;
case Constants.CONSTANT_String:
i = ((ConstantString) c).getStringIndex();
break;
default:
throw new RuntimeException(
"getConstantString called with illegal tag " + tag);
}
// Finally get the string from the constant pool
c = getConstant(i, Constants.CONSTANT_Utf8);
return ((ConstantUtf8) c).getBytes();
}
/** /**
* Retrieve constant at `index' from constant pool and resolve it to * @return Length of constant pool.
* a string representation. */
* public int getLength() {
* @param index of constant in constant pool return constant_pool_count;
* @param tag expected type }
* @return String representation
*/
public String constantToString( int index, byte tag ) throws ClassFormatException {
Constant c = getConstant(index, tag);
return constantToString(c);
}
/**
* @param constant
* Constant to set
*/
public void setConstant(int index, Constant constant) {
constant_pool[index] = constant;
}
/** /**
* Dump constant pool to file stream in binary format. * @param constant_pool
* */
* @param file Output file stream public void setConstantPool(Constant[] constant_pool) {
* @throws IOException this.constant_pool = constant_pool;
*/ constant_pool_count = (constant_pool == null) ? 0
public void dump( DataOutputStream file ) throws IOException { : constant_pool.length;
file.writeShort(constant_pool_count); }
for (int i = 1; i < constant_pool_count; i++) {
if (constant_pool[i] != null) {
constant_pool[i].dump(file);
}
}
}
/**
* @return String representation.
*/
@Override
public String toString() {
StringBuffer buf = new StringBuffer();
for (int i = 1; i < constant_pool_count; i++) {
buf.append(i).append(")").append(constant_pool[i]).append("\n");
}
return buf.toString();
}
/** /**
* Get constant from constant pool. * @return deep copy of this constant pool
* */
* @param index Index in constant pool public ConstantPool copy() {
* @return Constant value ConstantPool c = null;
* @see Constant try {
*/ c = (ConstantPool) clone();
public Constant getConstant( int index ) { c.constant_pool = new Constant[constant_pool_count];
if (index >= constant_pool.length || index < 0) { for (int i = 1; i < constant_pool_count; i++) {
throw new ClassFormatException("Invalid constant pool reference: " + index if (constant_pool[i] != null) {
+ ". Constant pool size is: " + constant_pool.length); c.constant_pool[i] = constant_pool[i].copy();
} }
return constant_pool[index]; }
} } catch (CloneNotSupportedException e) {
}
return c;
/** }
* Get constant from constant pool and check whether it has the
* expected type.
*
* @param index Index in constant pool
* @param tag Tag of expected constant, i.e., its type
* @return Constant value
* @see Constant
* @throws ClassFormatException
*/
public Constant getConstant( int index, byte tag ) throws ClassFormatException {
Constant c;
c = getConstant(index);
if (c == null) {
throw new ClassFormatException("Constant pool at index " + index + " is null.");
}
if (c.getTag() != tag) {
throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag]
+ "' at index " + index + " and got " + c);
}
return c;
}
/**
* @return Array of constants.
* @see Constant
*/
public Constant[] getConstantPool() {
return constant_pool;
}
/**
* Get string from constant pool and bypass the indirection of
* `ConstantClass' and `ConstantString' objects. I.e. these classes have
* an index field that points to another entry of the constant pool of
* type `ConstantUtf8' which contains the real data.
*
* @param index Index in constant pool
* @param tag Tag of expected constant, either ConstantClass or ConstantString
* @return Contents of string reference
* @see ConstantClass
* @see ConstantString
* @throws ClassFormatException
*/
public String getConstantString( int index, byte tag ) throws ClassFormatException {
Constant c;
int i;
c = getConstant(index, tag);
/* This switch() is not that elegant, since the two classes have the
* same contents, they just differ in the name of the index
* field variable.
* But we want to stick to the JVM naming conventions closely though
* we could have solved these more elegantly by using the same
* variable name or by subclassing.
*/
switch (tag) {
case Constants.CONSTANT_Class:
i = ((ConstantClass) c).getNameIndex();
break;
case Constants.CONSTANT_String:
i = ((ConstantString) c).getStringIndex();
break;
default:
throw new RuntimeException("getConstantString called with illegal tag " + tag);
}
// Finally get the string from the constant pool
c = getConstant(i, Constants.CONSTANT_Utf8);
return ((ConstantUtf8) c).getBytes();
}
/**
* @return Length of constant pool.
*/
public int getLength() {
return constant_pool_count;
}
/**
* @param constant Constant to set
*/
public void setConstant( int index, Constant constant ) {
constant_pool[index] = constant;
}
/**
* @param constant_pool
*/
public void setConstantPool( Constant[] constant_pool ) {
this.constant_pool = constant_pool;
constant_pool_count = (constant_pool == null) ? 0 : constant_pool.length;
}
/**
* @return String representation.
*/
public String toString() {
StringBuffer buf = new StringBuffer();
for (int i = 1; i < constant_pool_count; i++) {
buf.append(i).append(")").append(constant_pool[i]).append("\n");
}
return buf.toString();
}
/**
* @return deep copy of this constant pool
*/
public ConstantPool copy() {
ConstantPool c = null;
try {
c = (ConstantPool) clone();
c.constant_pool = new Constant[constant_pool_count];
for (int i = 1; i < constant_pool_count; i++) {
if (constant_pool[i] != null) {
c.constant_pool[i] = constant_pool[i].copy();
}
}
} catch (CloneNotSupportedException e) {
}
return c;
}
} }

View File

@ -21,107 +21,112 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from the abstract * This class is derived from the abstract <A
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class * HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* and represents a reference to a String object. * represents a reference to a String object.
* *
* @version $Id: ConstantString.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantString.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public final class ConstantString extends Constant implements ConstantObject { public final class ConstantString extends Constant implements ConstantObject {
private int string_index; // Identical to ConstantClass except for this name /**
*
*/
private static final long serialVersionUID = 1L;
private int string_index; // Identical to ConstantClass except for this name
/**
* Initialize from another object.
*/
public ConstantString(ConstantString c) {
this(c.getStringIndex());
}
/** /**
* Initialize from another object. * Initialize instance from file data.
*/ *
public ConstantString(ConstantString c) { * @param file
this(c.getStringIndex()); * Input stream
} * @throws IOException
*/
ConstantString(DataInputStream file) throws IOException {
this(file.readUnsignedShort());
}
/**
* @param string_index
* Index of Constant_Utf8 in constant pool
*/
public ConstantString(int string_index) {
super(Constants.CONSTANT_String);
this.string_index = string_index;
}
/** /**
* Initialize instance from file data. * Called by objects that are traversing the nodes of the tree implicitely
* * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param file Input stream * fields, attributes, etc. spawns a tree of objects.
* @throws IOException *
*/ * @param v
ConstantString(DataInputStream file) throws IOException { * Visitor object
this(file.readUnsignedShort()); */
} @Override
public void accept(Visitor v) {
v.visitConstantString(this);
}
/**
* Dump constant field reference to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeShort(string_index);
}
/** /**
* @param string_index Index of Constant_Utf8 in constant pool * @return Index in constant pool of the string (ConstantUtf8).
*/ */
public ConstantString(int string_index) { public final int getStringIndex() {
super(Constants.CONSTANT_String); return string_index;
this.string_index = string_index; }
}
/**
* @param string_index
* the index into the constant of the string value
*/
public final void setStringIndex(int string_index) {
this.string_index = string_index;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object return super.toString() + "(string_index = " + string_index + ")";
*/ }
public void accept( Visitor v ) {
v.visitConstantString(this);
}
/**
* @return String object
*/
@Override
public Object getConstantValue(ConstantPool cp) {
Constant c = cp.getConstant(string_index, Constants.CONSTANT_Utf8);
return ((ConstantUtf8) c).getBytes();
}
/** /**
* Dump constant field reference to file stream in binary format. * @return dereferenced string
* */
* @param file Output file stream public String getBytes(ConstantPool cp) {
* @throws IOException return (String) getConstantValue(cp);
*/ }
public final void dump( DataOutputStream file ) throws IOException {
file.writeByte(tag);
file.writeShort(string_index);
}
/**
* @return Index in constant pool of the string (ConstantUtf8).
*/
public final int getStringIndex() {
return string_index;
}
/**
* @param string_index the index into the constant of the string value
*/
public final void setStringIndex( int string_index ) {
this.string_index = string_index;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(string_index = " + string_index + ")";
}
/** @return String object
*/
public Object getConstantValue( ConstantPool cp ) {
Constant c = cp.getConstant(string_index, Constants.CONSTANT_Utf8);
return ((ConstantUtf8) c).getBytes();
}
/** @return dereferenced string
*/
public String getBytes( ConstantPool cp ) {
return (String) getConstantValue(cp);
}
} }

View File

@ -21,96 +21,101 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from the abstract * This class is derived from the abstract <A
* <A HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class * HREF="org.apache.bcel.classfile.Constant.html">Constant</A> class and
* and represents a reference to a Utf8 encoded string. * represents a reference to a Utf8 encoded string.
* *
* @version $Id: ConstantUtf8.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantUtf8.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Constant * @see Constant
*/ */
public final class ConstantUtf8 extends Constant { public final class ConstantUtf8 extends Constant {
private String bytes; /**
*
*/
private static final long serialVersionUID = 1L;
private String bytes;
/**
* Initialize from another object.
*/
public ConstantUtf8(ConstantUtf8 c) {
this(c.getBytes());
}
/** /**
* Initialize from another object. * Initialize instance from file data.
*/ *
public ConstantUtf8(ConstantUtf8 c) { * @param file
this(c.getBytes()); * Input stream
} * @throws IOException
*/
ConstantUtf8(DataInputStream file) throws IOException {
super(Constants.CONSTANT_Utf8);
bytes = file.readUTF();
}
/**
* @param bytes
* Data
*/
public ConstantUtf8(String bytes) {
super(Constants.CONSTANT_Utf8);
if (bytes == null) {
throw new IllegalArgumentException("bytes must not be null!");
}
this.bytes = bytes;
}
/** /**
* Initialize instance from file data. * Called by objects that are traversing the nodes of the tree implicitely
* * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param file Input stream * fields, attributes, etc. spawns a tree of objects.
* @throws IOException *
*/ * @param v
ConstantUtf8(DataInputStream file) throws IOException { * Visitor object
super(Constants.CONSTANT_Utf8); */
bytes = file.readUTF(); @Override
} public void accept(Visitor v) {
v.visitConstantUtf8(this);
}
/**
* Dump String in Utf8 format to file stream.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(tag);
file.writeUTF(bytes);
}
/** /**
* @param bytes Data * @return Data converted to string.
*/ */
public ConstantUtf8(String bytes) { public final String getBytes() {
super(Constants.CONSTANT_Utf8); return bytes;
if (bytes == null) { }
throw new IllegalArgumentException("bytes must not be null!");
}
this.bytes = bytes;
}
/**
* @param bytes
* the raw bytes of this Utf-8
*/
public final void setBytes(String bytes) {
this.bytes = bytes;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n")
*/ + "\")";
public void accept( Visitor v ) { }
v.visitConstantUtf8(this);
}
/**
* Dump String in Utf8 format to file stream.
*
* @param file Output file stream
* @throws IOException
*/
public final void dump( DataOutputStream file ) throws IOException {
file.writeByte(tag);
file.writeUTF(bytes);
}
/**
* @return Data converted to string.
*/
public final String getBytes() {
return bytes;
}
/**
* @param bytes the raw bytes of this Utf-8
*/
public final void setBytes( String bytes ) {
this.bytes = bytes;
}
/**
* @return String representation
*/
public final String toString() {
return super.toString() + "(\"" + Utility.replace(bytes, "\n", "\\n") + "\")";
}
} }

View File

@ -22,134 +22,147 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from <em>Attribute</em> and represents a constant * This class is derived from <em>Attribute</em> and represents a constant
* value, i.e., a default value for initializing a class field. * value, i.e., a default value for initializing a class field. This class is
* This class is instantiated by the <em>Attribute.readAttribute()</em> method. * instantiated by the <em>Attribute.readAttribute()</em> method.
* *
* @version $Id: ConstantValue.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantValue.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute * @see Attribute
*/ */
public final class ConstantValue extends Attribute { public final class ConstantValue extends Attribute {
private int constantvalue_index; /**
*
*/
private static final long serialVersionUID = 1L;
private int constantvalue_index;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public ConstantValue(ConstantValue c) {
this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c
.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * Construct object from file stream.
* references (shallow copy). Use clone() for a physical copy. *
*/ * @param name_index
public ConstantValue(ConstantValue c) { * Name index in constant pool
this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c.getConstantPool()); * @param length
} * Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
ConstantValue(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, file.readUnsignedShort(), constant_pool);
}
/**
* @param name_index
* Name index in constant pool
* @param length
* Content length in bytes
* @param constantvalue_index
* Index in constant pool
* @param constant_pool
* Array of constants
*/
public ConstantValue(int name_index, int length, int constantvalue_index,
ConstantPool constant_pool) {
super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool);
this.constantvalue_index = constantvalue_index;
}
/** /**
* Construct object from file stream. * Called by objects that are traversing the nodes of the tree implicitely
* @param name_index Name index in constant pool * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param length Content length in bytes * fields, attributes, etc. spawns a tree of objects.
* @param file Input stream *
* @param constant_pool Array of constants * @param v
* @throws IOException * Visitor object
*/ */
ConstantValue(int name_index, int length, DataInputStream file, ConstantPool constant_pool) @Override
throws IOException { public void accept(Visitor v) {
this(name_index, length, file.readUnsignedShort(), constant_pool); v.visitConstantValue(this);
} }
/**
* Dump constant value attribute to file stream on binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(constantvalue_index);
}
/** /**
* @param name_index Name index in constant pool * @return Index in constant pool of constant value.
* @param length Content length in bytes */
* @param constantvalue_index Index in constant pool public final int getConstantValueIndex() {
* @param constant_pool Array of constants return constantvalue_index;
*/ }
public ConstantValue(int name_index, int length, int constantvalue_index,
ConstantPool constant_pool) {
super(Constants.ATTR_CONSTANT_VALUE, name_index, length, constant_pool);
this.constantvalue_index = constantvalue_index;
}
/**
* @param constantvalue_index
* the index info the constant pool of this constant value
*/
public final void setConstantValueIndex(int constantvalue_index) {
this.constantvalue_index = constantvalue_index;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation of constant value.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object Constant c = constant_pool.getConstant(constantvalue_index);
*/ String buf;
public void accept( Visitor v ) { int i;
v.visitConstantValue(this); // Print constant to string depending on its type
} switch (c.getTag()) {
case Constants.CONSTANT_Long:
buf = "" + ((ConstantLong) c).getBytes();
break;
case Constants.CONSTANT_Float:
buf = "" + ((ConstantFloat) c).getBytes();
break;
case Constants.CONSTANT_Double:
buf = "" + ((ConstantDouble) c).getBytes();
break;
case Constants.CONSTANT_Integer:
buf = "" + ((ConstantInteger) c).getBytes();
break;
case Constants.CONSTANT_String:
i = ((ConstantString) c).getStringIndex();
c = constant_pool.getConstant(i, Constants.CONSTANT_Utf8);
buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes())
+ "\"";
break;
default:
throw new IllegalStateException("Type of ConstValue invalid: " + c);
}
return buf;
}
/**
/** * @return deep copy of this attribute
* Dump constant value attribute to file stream on binary format. */
* @Override
* @param file Output file stream public Attribute copy(ConstantPool _constant_pool) {
* @throws IOException ConstantValue c = (ConstantValue) clone();
*/ c.constant_pool = _constant_pool;
public final void dump( DataOutputStream file ) throws IOException { return c;
super.dump(file); }
file.writeShort(constantvalue_index);
}
/**
* @return Index in constant pool of constant value.
*/
public final int getConstantValueIndex() {
return constantvalue_index;
}
/**
* @param constantvalue_index the index info the constant pool of this constant value
*/
public final void setConstantValueIndex( int constantvalue_index ) {
this.constantvalue_index = constantvalue_index;
}
/**
* @return String representation of constant value.
*/
public final String toString() {
Constant c = constant_pool.getConstant(constantvalue_index);
String buf;
int i;
// Print constant to string depending on its type
switch (c.getTag()) {
case Constants.CONSTANT_Long:
buf = "" + ((ConstantLong) c).getBytes();
break;
case Constants.CONSTANT_Float:
buf = "" + ((ConstantFloat) c).getBytes();
break;
case Constants.CONSTANT_Double:
buf = "" + ((ConstantDouble) c).getBytes();
break;
case Constants.CONSTANT_Integer:
buf = "" + ((ConstantInteger) c).getBytes();
break;
case Constants.CONSTANT_String:
i = ((ConstantString) c).getStringIndex();
c = constant_pool.getConstant(i, Constants.CONSTANT_Utf8);
buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\"";
break;
default:
throw new IllegalStateException("Type of ConstValue invalid: " + c);
}
return buf;
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
ConstantValue c = (ConstantValue) clone();
c.constant_pool = _constant_pool;
return c;
}
} }

View File

@ -23,118 +23,130 @@ import org.apache.bcel.Constants;
/** /**
* This class is derived from <em>Attribute</em> and denotes that this is a * This class is derived from <em>Attribute</em> and denotes that this is a
* deprecated method. * deprecated method. It is instantiated from the
* It is instantiated from the <em>Attribute.readAttribute()</em> method. * <em>Attribute.readAttribute()</em> method.
* *
* @version $Id: Deprecated.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Deprecated.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute * @see Attribute
*/ */
public final class Deprecated extends Attribute { public final class Deprecated extends Attribute {
private byte[] bytes; /**
*
*/
private static final long serialVersionUID = 1L;
private byte[] bytes;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public Deprecated(Deprecated c) {
this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * @param name_index
* references (shallow copy). Use clone() for a physical copy. * Index in constant pool to CONSTANT_Utf8
*/ * @param length
public Deprecated(Deprecated c) { * Content length in bytes
this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); * @param bytes
} * Attribute contents
* @param constant_pool
* Array of constants
*/
public Deprecated(int name_index, int length, byte[] bytes,
ConstantPool constant_pool) {
super(Constants.ATTR_DEPRECATED, name_index, length, constant_pool);
this.bytes = bytes;
}
/**
* Construct object from file stream.
*
* @param name_index
* Index in constant pool to CONSTANT_Utf8
* @param length
* Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
Deprecated(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, (byte[]) null, constant_pool);
if (length > 0) {
bytes = new byte[length];
file.readFully(bytes);
System.err.println("Deprecated attribute with length > 0");
}
}
/** /**
* @param name_index Index in constant pool to CONSTANT_Utf8 * Called by objects that are traversing the nodes of the tree implicitely
* @param length Content length in bytes * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param bytes Attribute contents * fields, attributes, etc. spawns a tree of objects.
* @param constant_pool Array of constants *
*/ * @param v
public Deprecated(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { * Visitor object
super(Constants.ATTR_DEPRECATED, name_index, length, constant_pool); */
this.bytes = bytes; @Override
} public void accept(Visitor v) {
v.visitDeprecated(this);
}
/**
* Dump source file attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
if (length > 0) {
file.write(bytes, 0, length);
}
}
/** /**
* Construct object from file stream. * @return data bytes.
* @param name_index Index in constant pool to CONSTANT_Utf8 */
* @param length Content length in bytes public final byte[] getBytes() {
* @param file Input stream return bytes;
* @param constant_pool Array of constants }
* @throws IOException
*/
Deprecated(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, (byte[]) null, constant_pool);
if (length > 0) {
bytes = new byte[length];
file.readFully(bytes);
System.err.println("Deprecated attribute with length > 0");
}
}
/**
* @param bytes
* the raw bytes that represents this byte array
*/
public final void setBytes(byte[] bytes) {
this.bytes = bytes;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return attribute name
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED];
*/ }
public void accept( Visitor v ) {
v.visitDeprecated(this);
}
/**
/** * @return deep copy of this attribute
* Dump source file attribute to file stream in binary format. */
* @Override
* @param file Output file stream public Attribute copy(ConstantPool _constant_pool) {
* @throws IOException Deprecated c = (Deprecated) clone();
*/ if (bytes != null) {
public final void dump( DataOutputStream file ) throws IOException { c.bytes = new byte[bytes.length];
super.dump(file); System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
if (length > 0) { }
file.write(bytes, 0, length); c.constant_pool = _constant_pool;
} return c;
} }
/**
* @return data bytes.
*/
public final byte[] getBytes() {
return bytes;
}
/**
* @param bytes the raw bytes that represents this byte array
*/
public final void setBytes( byte[] bytes ) {
this.bytes = bytes;
}
/**
* @return attribute name
*/
public final String toString() {
return Constants.ATTRIBUTE_NAMES[Constants.ATTR_DEPRECATED];
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
Deprecated c = (Deprecated) clone();
if (bytes != null) {
c.bytes = new byte[bytes.length];
System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
}
c.constant_pool = _constant_pool;
return c;
}
} }

View File

@ -19,338 +19,338 @@ package org.apache.bcel.classfile;
import java.util.Stack; import java.util.Stack;
/** /**
* Traverses a JavaClass with another Visitor object 'piggy-backed' * Traverses a JavaClass with another Visitor object 'piggy-backed' that is
* that is applied to all components of a JavaClass object. I.e. this * applied to all components of a JavaClass object. I.e. this class supplies the
* class supplies the traversal strategy, other classes can make use * traversal strategy, other classes can make use of it.
* of it. *
*
* @version $Id: DescendingVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $ * @version $Id: DescendingVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DescendingVisitor implements Visitor { public class DescendingVisitor implements Visitor {
private JavaClass clazz; private JavaClass clazz;
private Visitor visitor; private Visitor visitor;
private Stack stack = new Stack(); private Stack<Cloneable> stack = new Stack<Cloneable>();
/**
/** @return container of current entitity, i.e., predecessor during traversal * @return container of current entitity, i.e., predecessor during traversal
*/ */
public Object predecessor() { public Object predecessor() {
return predecessor(0); return predecessor(0);
} }
/**
/** * @param level
* @param level nesting level, i.e., 0 returns the direct predecessor * nesting level, i.e., 0 returns the direct predecessor
* @return container of current entitity, i.e., predecessor during traversal * @return container of current entitity, i.e., predecessor during traversal
*/ */
public Object predecessor( int level ) { public Object predecessor(int level) {
int size = stack.size(); int size = stack.size();
if ((size < 2) || (level < 0)) { if ((size < 2) || (level < 0)) {
return null; return null;
} else { } else {
return stack.elementAt(size - (level + 2)); // size - 1 == current return stack.elementAt(size - (level + 2)); // size - 1 == current
} }
} }
/**
/** @return current object * @return current object
*/ */
public Object current() { public Object current() {
return stack.peek(); return stack.peek();
} }
/**
/** * @param clazz
* @param clazz Class to traverse * Class to traverse
* @param visitor visitor object to apply to all components * @param visitor
*/ * visitor object to apply to all components
public DescendingVisitor(JavaClass clazz, Visitor visitor) { */
this.clazz = clazz; public DescendingVisitor(JavaClass clazz, Visitor visitor) {
this.visitor = visitor; this.clazz = clazz;
} this.visitor = visitor;
}
/** /**
* Start traversal. * Start traversal.
*/ */
public void visit() { public void visit() {
clazz.accept(this); clazz.accept(this);
} }
@Override
public void visitJavaClass( JavaClass _clazz ) { public void visitJavaClass(JavaClass _clazz) {
stack.push(_clazz); stack.push(_clazz);
_clazz.accept(visitor); _clazz.accept(visitor);
Field[] fields = _clazz.getFields(); Field[] fields = _clazz.getFields();
for (int i = 0; i < fields.length; i++) { for (int i = 0; i < fields.length; i++) {
fields[i].accept(this); fields[i].accept(this);
} }
Method[] methods = _clazz.getMethods(); Method[] methods = _clazz.getMethods();
for (int i = 0; i < methods.length; i++) { for (int i = 0; i < methods.length; i++) {
methods[i].accept(this); methods[i].accept(this);
} }
Attribute[] attributes = _clazz.getAttributes(); Attribute[] attributes = _clazz.getAttributes();
for (int i = 0; i < attributes.length; i++) { for (int i = 0; i < attributes.length; i++) {
attributes[i].accept(this); attributes[i].accept(this);
} }
_clazz.getConstantPool().accept(this); _clazz.getConstantPool().accept(this);
stack.pop(); stack.pop();
} }
@Override
public void visitField( Field field ) { public void visitField(Field field) {
stack.push(field); stack.push(field);
field.accept(visitor); field.accept(visitor);
Attribute[] attributes = field.getAttributes(); Attribute[] attributes = field.getAttributes();
for (int i = 0; i < attributes.length; i++) { for (int i = 0; i < attributes.length; i++) {
attributes[i].accept(this); attributes[i].accept(this);
} }
stack.pop(); stack.pop();
} }
@Override
public void visitConstantValue( ConstantValue cv ) { public void visitConstantValue(ConstantValue cv) {
stack.push(cv); stack.push(cv);
cv.accept(visitor); cv.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitMethod( Method method ) { public void visitMethod(Method method) {
stack.push(method); stack.push(method);
method.accept(visitor); method.accept(visitor);
Attribute[] attributes = method.getAttributes(); Attribute[] attributes = method.getAttributes();
for (int i = 0; i < attributes.length; i++) { for (int i = 0; i < attributes.length; i++) {
attributes[i].accept(this); attributes[i].accept(this);
} }
stack.pop(); stack.pop();
} }
@Override
public void visitExceptionTable( ExceptionTable table ) { public void visitExceptionTable(ExceptionTable table) {
stack.push(table); stack.push(table);
table.accept(visitor); table.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitCode( Code code ) { public void visitCode(Code code) {
stack.push(code); stack.push(code);
code.accept(visitor); code.accept(visitor);
CodeException[] table = code.getExceptionTable(); CodeException[] table = code.getExceptionTable();
for (int i = 0; i < table.length; i++) { for (int i = 0; i < table.length; i++) {
table[i].accept(this); table[i].accept(this);
} }
Attribute[] attributes = code.getAttributes(); Attribute[] attributes = code.getAttributes();
for (int i = 0; i < attributes.length; i++) { for (int i = 0; i < attributes.length; i++) {
attributes[i].accept(this); attributes[i].accept(this);
} }
stack.pop(); stack.pop();
} }
@Override
public void visitCodeException( CodeException ce ) { public void visitCodeException(CodeException ce) {
stack.push(ce); stack.push(ce);
ce.accept(visitor); ce.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitLineNumberTable( LineNumberTable table ) { public void visitLineNumberTable(LineNumberTable table) {
stack.push(table); stack.push(table);
table.accept(visitor); table.accept(visitor);
LineNumber[] numbers = table.getLineNumberTable(); LineNumber[] numbers = table.getLineNumberTable();
for (int i = 0; i < numbers.length; i++) { for (int i = 0; i < numbers.length; i++) {
numbers[i].accept(this); numbers[i].accept(this);
} }
stack.pop(); stack.pop();
} }
@Override
public void visitLineNumber( LineNumber number ) { public void visitLineNumber(LineNumber number) {
stack.push(number); stack.push(number);
number.accept(visitor); number.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitLocalVariableTable( LocalVariableTable table ) { public void visitLocalVariableTable(LocalVariableTable table) {
stack.push(table); stack.push(table);
table.accept(visitor); table.accept(visitor);
LocalVariable[] vars = table.getLocalVariableTable(); LocalVariable[] vars = table.getLocalVariableTable();
for (int i = 0; i < vars.length; i++) { for (int i = 0; i < vars.length; i++) {
vars[i].accept(this); vars[i].accept(this);
} }
stack.pop(); stack.pop();
} }
@Override
public void visitStackMap( StackMap table ) { public void visitStackMap(StackMap table) {
stack.push(table); stack.push(table);
table.accept(visitor); table.accept(visitor);
StackMapEntry[] vars = table.getStackMap(); StackMapEntry[] vars = table.getStackMap();
for (int i = 0; i < vars.length; i++) { for (int i = 0; i < vars.length; i++) {
vars[i].accept(this); vars[i].accept(this);
} }
stack.pop(); stack.pop();
} }
@Override
public void visitStackMapEntry( StackMapEntry var ) { public void visitStackMapEntry(StackMapEntry var) {
stack.push(var); stack.push(var);
var.accept(visitor); var.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitLocalVariable( LocalVariable var ) { public void visitLocalVariable(LocalVariable var) {
stack.push(var); stack.push(var);
var.accept(visitor); var.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitConstantPool( ConstantPool cp ) { public void visitConstantPool(ConstantPool cp) {
stack.push(cp); stack.push(cp);
cp.accept(visitor); cp.accept(visitor);
Constant[] constants = cp.getConstantPool(); Constant[] constants = cp.getConstantPool();
for (int i = 1; i < constants.length; i++) { for (int i = 1; i < constants.length; i++) {
if (constants[i] != null) { if (constants[i] != null) {
constants[i].accept(this); constants[i].accept(this);
} }
} }
stack.pop(); stack.pop();
} }
@Override
public void visitConstantClass( ConstantClass constant ) { public void visitConstantClass(ConstantClass constant) {
stack.push(constant); stack.push(constant);
constant.accept(visitor); constant.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitConstantDouble( ConstantDouble constant ) { public void visitConstantDouble(ConstantDouble constant) {
stack.push(constant); stack.push(constant);
constant.accept(visitor); constant.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitConstantFieldref( ConstantFieldref constant ) { public void visitConstantFieldref(ConstantFieldref constant) {
stack.push(constant); stack.push(constant);
constant.accept(visitor); constant.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitConstantFloat( ConstantFloat constant ) { public void visitConstantFloat(ConstantFloat constant) {
stack.push(constant); stack.push(constant);
constant.accept(visitor); constant.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitConstantInteger( ConstantInteger constant ) { public void visitConstantInteger(ConstantInteger constant) {
stack.push(constant); stack.push(constant);
constant.accept(visitor); constant.accept(visitor);
stack.pop(); stack.pop();
} }
@Override
public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref constant ) { public void visitConstantInterfaceMethodref(
stack.push(constant); ConstantInterfaceMethodref constant) {
constant.accept(visitor); stack.push(constant);
stack.pop(); constant.accept(visitor);
} stack.pop();
}
public void visitConstantLong( ConstantLong constant ) { @Override
stack.push(constant); public void visitConstantLong(ConstantLong constant) {
constant.accept(visitor); stack.push(constant);
stack.pop(); constant.accept(visitor);
} stack.pop();
}
public void visitConstantMethodref( ConstantMethodref constant ) { @Override
stack.push(constant); public void visitConstantMethodref(ConstantMethodref constant) {
constant.accept(visitor); stack.push(constant);
stack.pop(); constant.accept(visitor);
} stack.pop();
}
public void visitConstantNameAndType( ConstantNameAndType constant ) { @Override
stack.push(constant); public void visitConstantNameAndType(ConstantNameAndType constant) {
constant.accept(visitor); stack.push(constant);
stack.pop(); constant.accept(visitor);
} stack.pop();
}
public void visitConstantString( ConstantString constant ) { @Override
stack.push(constant); public void visitConstantString(ConstantString constant) {
constant.accept(visitor); stack.push(constant);
stack.pop(); constant.accept(visitor);
} stack.pop();
}
public void visitConstantUtf8( ConstantUtf8 constant ) { @Override
stack.push(constant); public void visitConstantUtf8(ConstantUtf8 constant) {
constant.accept(visitor); stack.push(constant);
stack.pop(); constant.accept(visitor);
} stack.pop();
}
public void visitInnerClasses( InnerClasses ic ) { @Override
stack.push(ic); public void visitInnerClasses(InnerClasses ic) {
ic.accept(visitor); stack.push(ic);
InnerClass[] ics = ic.getInnerClasses(); ic.accept(visitor);
for (int i = 0; i < ics.length; i++) { InnerClass[] ics = ic.getInnerClasses();
ics[i].accept(this); for (int i = 0; i < ics.length; i++) {
} ics[i].accept(this);
stack.pop(); }
} stack.pop();
}
public void visitInnerClass( InnerClass inner ) { @Override
stack.push(inner); public void visitInnerClass(InnerClass inner) {
inner.accept(visitor); stack.push(inner);
stack.pop(); inner.accept(visitor);
} stack.pop();
}
public void visitDeprecated( Deprecated attribute ) { @Override
stack.push(attribute); public void visitDeprecated(Deprecated attribute) {
attribute.accept(visitor); stack.push(attribute);
stack.pop(); attribute.accept(visitor);
} stack.pop();
}
public void visitSignature( Signature attribute ) { @Override
stack.push(attribute); public void visitSignature(Signature attribute) {
attribute.accept(visitor); stack.push(attribute);
stack.pop(); attribute.accept(visitor);
} stack.pop();
}
public void visitSourceFile( SourceFile attribute ) { @Override
stack.push(attribute); public void visitSourceFile(SourceFile attribute) {
attribute.accept(visitor); stack.push(attribute);
stack.pop(); attribute.accept(visitor);
} stack.pop();
}
public void visitSynthetic( Synthetic attribute ) { @Override
stack.push(attribute); public void visitSynthetic(Synthetic attribute) {
attribute.accept(visitor); stack.push(attribute);
stack.pop(); attribute.accept(visitor);
} stack.pop();
}
public void visitUnknown( Unknown attribute ) { @Override
stack.push(attribute); public void visitUnknown(Unknown attribute) {
attribute.accept(visitor); stack.push(attribute);
stack.pop(); attribute.accept(visitor);
} stack.pop();
}
} }

View File

@ -17,145 +17,145 @@
package org.apache.bcel.classfile; package org.apache.bcel.classfile;
/** /**
* Visitor with empty method bodies, can be extended and used in conjunction with the * Visitor with empty method bodies, can be extended and used in conjunction
* DescendingVisitor class, e.g. * with the DescendingVisitor class, e.g.
* *
* By courtesy of David Spencer. * By courtesy of David Spencer.
* *
* @see DescendingVisitor * @see DescendingVisitor
* @version $Id: EmptyVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $ * @version $Id: EmptyVisitor.java 388707 2006-03-25 05:40:28Z tcurdt $
* *
*/ */
public class EmptyVisitor implements Visitor { public class EmptyVisitor implements Visitor {
protected EmptyVisitor() { protected EmptyVisitor() {
} }
@Override
public void visitCode(Code obj) {
}
public void visitCode( Code obj ) { @Override
} public void visitCodeException(CodeException obj) {
}
@Override
public void visitConstantClass(ConstantClass obj) {
}
public void visitCodeException( CodeException obj ) { @Override
} public void visitConstantDouble(ConstantDouble obj) {
}
@Override
public void visitConstantFieldref(ConstantFieldref obj) {
}
public void visitConstantClass( ConstantClass obj ) { @Override
} public void visitConstantFloat(ConstantFloat obj) {
}
@Override
public void visitConstantInteger(ConstantInteger obj) {
}
public void visitConstantDouble( ConstantDouble obj ) { @Override
} public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj) {
}
@Override
public void visitConstantLong(ConstantLong obj) {
}
public void visitConstantFieldref( ConstantFieldref obj ) { @Override
} public void visitConstantMethodref(ConstantMethodref obj) {
}
@Override
public void visitConstantNameAndType(ConstantNameAndType obj) {
}
public void visitConstantFloat( ConstantFloat obj ) { @Override
} public void visitConstantPool(ConstantPool obj) {
}
@Override
public void visitConstantString(ConstantString obj) {
}
public void visitConstantInteger( ConstantInteger obj ) { @Override
} public void visitConstantUtf8(ConstantUtf8 obj) {
}
@Override
public void visitConstantValue(ConstantValue obj) {
}
public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref obj ) { @Override
} public void visitDeprecated(Deprecated obj) {
}
@Override
public void visitExceptionTable(ExceptionTable obj) {
}
public void visitConstantLong( ConstantLong obj ) { @Override
} public void visitField(Field obj) {
}
@Override
public void visitInnerClass(InnerClass obj) {
}
public void visitConstantMethodref( ConstantMethodref obj ) { @Override
} public void visitInnerClasses(InnerClasses obj) {
}
@Override
public void visitJavaClass(JavaClass obj) {
}
public void visitConstantNameAndType( ConstantNameAndType obj ) { @Override
} public void visitLineNumber(LineNumber obj) {
}
@Override
public void visitLineNumberTable(LineNumberTable obj) {
}
public void visitConstantPool( ConstantPool obj ) { @Override
} public void visitLocalVariable(LocalVariable obj) {
}
@Override
public void visitLocalVariableTable(LocalVariableTable obj) {
}
public void visitConstantString( ConstantString obj ) { @Override
} public void visitMethod(Method obj) {
}
@Override
public void visitSignature(Signature obj) {
}
public void visitConstantUtf8( ConstantUtf8 obj ) { @Override
} public void visitSourceFile(SourceFile obj) {
}
@Override
public void visitSynthetic(Synthetic obj) {
}
public void visitConstantValue( ConstantValue obj ) { @Override
} public void visitUnknown(Unknown obj) {
}
@Override
public void visitStackMap(StackMap obj) {
}
public void visitDeprecated( Deprecated obj ) { @Override
} public void visitStackMapEntry(StackMapEntry obj) {
}
public void visitExceptionTable( ExceptionTable obj ) {
}
public void visitField( Field obj ) {
}
public void visitInnerClass( InnerClass obj ) {
}
public void visitInnerClasses( InnerClasses obj ) {
}
public void visitJavaClass( JavaClass obj ) {
}
public void visitLineNumber( LineNumber obj ) {
}
public void visitLineNumberTable( LineNumberTable obj ) {
}
public void visitLocalVariable( LocalVariable obj ) {
}
public void visitLocalVariableTable( LocalVariableTable obj ) {
}
public void visitMethod( Method obj ) {
}
public void visitSignature( Signature obj ) {
}
public void visitSourceFile( SourceFile obj ) {
}
public void visitSynthetic( Synthetic obj ) {
}
public void visitUnknown( Unknown obj ) {
}
public void visitStackMap( StackMap obj ) {
}
public void visitStackMapEntry( StackMapEntry obj ) {
}
} }

View File

@ -21,160 +21,171 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents the table of exceptions that are thrown by a * This class represents the table of exceptions that are thrown by a method.
* method. This attribute may be used once per method. The name of * This attribute may be used once per method. The name of this class is
* this class is <em>ExceptionTable</em> for historical reasons; The * <em>ExceptionTable</em> for historical reasons; The Java Virtual Machine
* Java Virtual Machine Specification, Second Edition defines this * Specification, Second Edition defines this attribute using the name
* attribute using the name <em>Exceptions</em> (which is inconsistent * <em>Exceptions</em> (which is inconsistent with the other classes).
* with the other classes). *
*
* @version $Id: ExceptionTable.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ExceptionTable.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code * @see Code
*/ */
public final class ExceptionTable extends Attribute { public final class ExceptionTable extends Attribute {
private int number_of_exceptions; // Table of indices into /**
private int[] exception_index_table; // constant pool *
*/
private static final long serialVersionUID = 1L;
private int number_of_exceptions; // Table of indices into
private int[] exception_index_table; // constant pool
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use copy() for a physical copy.
*/
public ExceptionTable(ExceptionTable c) {
this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c
.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * @param name_index
* references (shallow copy). Use copy() for a physical copy. * Index in constant pool
*/ * @param length
public ExceptionTable(ExceptionTable c) { * Content length in bytes
this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(), c.getConstantPool()); * @param exception_index_table
} * Table of indices in constant pool
* @param constant_pool
* Array of constants
*/
public ExceptionTable(int name_index, int length,
int[] exception_index_table, ConstantPool constant_pool) {
super(Constants.ATTR_EXCEPTIONS, name_index, length, constant_pool);
setExceptionIndexTable(exception_index_table);
}
/**
* Construct object from file stream.
*
* @param name_index
* Index in constant pool
* @param length
* Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
ExceptionTable(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, (int[]) null, constant_pool);
number_of_exceptions = file.readUnsignedShort();
exception_index_table = new int[number_of_exceptions];
for (int i = 0; i < number_of_exceptions; i++) {
exception_index_table[i] = file.readUnsignedShort();
}
}
/** /**
* @param name_index Index in constant pool * Called by objects that are traversing the nodes of the tree implicitely
* @param length Content length in bytes * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param exception_index_table Table of indices in constant pool * fields, attributes, etc. spawns a tree of objects.
* @param constant_pool Array of constants *
*/ * @param v
public ExceptionTable(int name_index, int length, int[] exception_index_table, * Visitor object
ConstantPool constant_pool) { */
super(Constants.ATTR_EXCEPTIONS, name_index, length, constant_pool); @Override
setExceptionIndexTable(exception_index_table); public void accept(Visitor v) {
} v.visitExceptionTable(this);
}
/**
* Dump exceptions attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(number_of_exceptions);
for (int i = 0; i < number_of_exceptions; i++) {
file.writeShort(exception_index_table[i]);
}
}
/** /**
* Construct object from file stream. * @return Array of indices into constant pool of thrown exceptions.
* @param name_index Index in constant pool */
* @param length Content length in bytes public final int[] getExceptionIndexTable() {
* @param file Input stream return exception_index_table;
* @param constant_pool Array of constants }
* @throws IOException
*/
ExceptionTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, (int[]) null, constant_pool);
number_of_exceptions = file.readUnsignedShort();
exception_index_table = new int[number_of_exceptions];
for (int i = 0; i < number_of_exceptions; i++) {
exception_index_table[i] = file.readUnsignedShort();
}
}
/**
* @return Length of exception table.
*/
public final int getNumberOfExceptions() {
return number_of_exceptions;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return class names of thrown exceptions
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final String[] getExceptionNames() {
* String[] names = new String[number_of_exceptions];
* @param v Visitor object for (int i = 0; i < number_of_exceptions; i++) {
*/ names[i] = constant_pool.getConstantString(
public void accept( Visitor v ) { exception_index_table[i], Constants.CONSTANT_Class)
v.visitExceptionTable(this); .replace('/', '.');
} }
return names;
}
/**
* @param exception_index_table
* the list of exception indexes Also redefines
* number_of_exceptions according to table length.
*/
public final void setExceptionIndexTable(int[] exception_index_table) {
this.exception_index_table = exception_index_table;
number_of_exceptions = (exception_index_table == null) ? 0
: exception_index_table.length;
}
/** /**
* Dump exceptions attribute to file stream in binary format. * @return String representation, i.e., a list of thrown exceptions.
* */
* @param file Output file stream @Override
* @throws IOException public final String toString() {
*/ StringBuffer buf = new StringBuffer("");
public final void dump( DataOutputStream file ) throws IOException { String str;
super.dump(file); for (int i = 0; i < number_of_exceptions; i++) {
file.writeShort(number_of_exceptions); str = constant_pool.getConstantString(exception_index_table[i],
for (int i = 0; i < number_of_exceptions; i++) { Constants.CONSTANT_Class);
file.writeShort(exception_index_table[i]); buf.append(Utility.compactClassName(str, false));
} if (i < number_of_exceptions - 1) {
} buf.append(", ");
}
}
return buf.toString();
}
/**
/** * @return deep copy of this attribute
* @return Array of indices into constant pool of thrown exceptions. */
*/ @Override
public final int[] getExceptionIndexTable() { public Attribute copy(ConstantPool _constant_pool) {
return exception_index_table; ExceptionTable c = (ExceptionTable) clone();
} if (exception_index_table != null) {
c.exception_index_table = new int[exception_index_table.length];
System.arraycopy(exception_index_table, 0, c.exception_index_table,
/** 0, exception_index_table.length);
* @return Length of exception table. }
*/ c.constant_pool = _constant_pool;
public final int getNumberOfExceptions() { return c;
return number_of_exceptions; }
}
/**
* @return class names of thrown exceptions
*/
public final String[] getExceptionNames() {
String[] names = new String[number_of_exceptions];
for (int i = 0; i < number_of_exceptions; i++) {
names[i] = constant_pool.getConstantString(exception_index_table[i],
Constants.CONSTANT_Class).replace('/', '.');
}
return names;
}
/**
* @param exception_index_table the list of exception indexes
* Also redefines number_of_exceptions according to table length.
*/
public final void setExceptionIndexTable( int[] exception_index_table ) {
this.exception_index_table = exception_index_table;
number_of_exceptions = (exception_index_table == null) ? 0 : exception_index_table.length;
}
/**
* @return String representation, i.e., a list of thrown exceptions.
*/
public final String toString() {
StringBuffer buf = new StringBuffer("");
String str;
for (int i = 0; i < number_of_exceptions; i++) {
str = constant_pool.getConstantString(exception_index_table[i],
Constants.CONSTANT_Class);
buf.append(Utility.compactClassName(str, false));
if (i < number_of_exceptions - 1) {
buf.append(", ");
}
}
return buf.toString();
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
ExceptionTable c = (ExceptionTable) clone();
if (exception_index_table != null) {
c.exception_index_table = new int[exception_index_table.length];
System.arraycopy(exception_index_table, 0, c.exception_index_table, 0,
exception_index_table.length);
}
c.constant_pool = _constant_pool;
return c;
}
} }

View File

@ -23,168 +23,175 @@ import org.apache.bcel.generic.Type;
import org.apache.bcel.util.BCELComparator; import org.apache.bcel.util.BCELComparator;
/** /**
* This class represents the field info structure, i.e., the representation * This class represents the field info structure, i.e., the representation for
* for a variable in the class. See JVM specification for details. * a variable in the class. See JVM specification for details.
* *
* @version $Id: Field.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Field.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class Field extends FieldOrMethod { public final class Field extends FieldOrMethod {
private static BCELComparator _cmp = new BCELComparator() { /**
*
*/
private static final long serialVersionUID = 1L;
private static BCELComparator _cmp = new BCELComparator() {
public boolean equals( Object o1, Object o2 ) { @Override
Field THIS = (Field) o1; public boolean equals(Object o1, Object o2) {
Field THAT = (Field) o2; Field THIS = (Field) o1;
return THIS.getName().equals(THAT.getName()) Field THAT = (Field) o2;
&& THIS.getSignature().equals(THAT.getSignature()); return THIS.getName().equals(THAT.getName())
} && THIS.getSignature().equals(THAT.getSignature());
}
@Override
public int hashCode(Object o) {
Field THIS = (Field) o;
return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
}
};
public int hashCode( Object o ) { /**
Field THIS = (Field) o; * Initialize from another object. Note that both objects use the same
return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); * references (shallow copy). Use clone() for a physical copy.
} */
}; public Field(Field c) {
super(c);
}
/**
* Construct object from file stream.
*
* @param file
* Input stream
*/
Field(DataInputStream file, ConstantPool constant_pool) throws IOException,
ClassFormatException {
super(file, constant_pool);
}
/** /**
* Initialize from another object. Note that both objects use the same * @param access_flags
* references (shallow copy). Use clone() for a physical copy. * Access rights of field
*/ * @param name_index
public Field(Field c) { * Points to field name in constant pool
super(c); * @param signature_index
} * Points to encoded signature
* @param attributes
* Collection of attributes
* @param constant_pool
* Array of constants
*/
public Field(int access_flags, int name_index, int signature_index,
Attribute[] attributes, ConstantPool constant_pool) {
super(access_flags, name_index, signature_index, attributes,
constant_pool);
}
/**
* Called by objects that are traversing the nodes of the tree implicitely
* defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v
* Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitField(this);
}
/** /**
* Construct object from file stream. * @return constant value associated with this field (may be null)
* @param file Input stream */
*/ public final ConstantValue getConstantValue() {
Field(DataInputStream file, ConstantPool constant_pool) throws IOException, for (int i = 0; i < attributes_count; i++) {
ClassFormatException { if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) {
super(file, constant_pool); return (ConstantValue) attributes[i];
} }
}
return null;
}
/**
* Return string representation close to declaration format, `public static
* final short MAX = 100', e.g..
*
* @return String representation of field, including the signature.
*/
@Override
public final String toString() {
String name, signature, access; // Short cuts to constant pool
// Get names from constant pool
access = Utility.accessToString(access_flags);
access = access.equals("") ? "" : (access + " ");
signature = Utility.signatureToString(getSignature());
name = getName();
StringBuffer buf = new StringBuffer(64);
buf.append(access).append(signature).append(" ").append(name);
ConstantValue cv = getConstantValue();
if (cv != null) {
buf.append(" = ").append(cv);
}
for (int i = 0; i < attributes_count; i++) {
Attribute a = attributes[i];
if (!(a instanceof ConstantValue)) {
buf.append(" [").append(a.toString()).append("]");
}
}
return buf.toString();
}
/** /**
* @param access_flags Access rights of field * @return deep copy of this field
* @param name_index Points to field name in constant pool */
* @param signature_index Points to encoded signature public final Field copy(ConstantPool _constant_pool) {
* @param attributes Collection of attributes return (Field) copy_(_constant_pool);
* @param constant_pool Array of constants }
*/
public Field(int access_flags, int name_index, int signature_index, Attribute[] attributes,
ConstantPool constant_pool) {
super(access_flags, name_index, signature_index, attributes, constant_pool);
}
/**
* @return type of field
*/
public Type getType() {
return Type.getReturnType(getSignature());
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return Comparison strategy object
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public static BCELComparator getComparator() {
* return _cmp;
* @param v Visitor object }
*/
public void accept( Visitor v ) {
v.visitField(this);
}
/**
* @param comparator
* Comparison strategy object
*/
public static void setComparator(BCELComparator comparator) {
_cmp = comparator;
}
/** /**
* @return constant value associated with this field (may be null) * Return value as defined by given BCELComparator strategy. By default two
*/ * Field objects are said to be equal when their names and signatures are
public final ConstantValue getConstantValue() { * equal.
for (int i = 0; i < attributes_count; i++) { *
if (attributes[i].getTag() == Constants.ATTR_CONSTANT_VALUE) { * @see java.lang.Object#equals(java.lang.Object)
return (ConstantValue) attributes[i]; */
} @Override
} public boolean equals(Object obj) {
return null; return _cmp.equals(this, obj);
} }
/**
/** * Return value as defined by given BCELComparator strategy. By default
* Return string representation close to declaration format, * return the hashcode of the field's name XOR signature.
* `public static final short MAX = 100', e.g.. *
* * @see java.lang.Object#hashCode()
* @return String representation of field, including the signature. */
*/ @Override
public final String toString() { public int hashCode() {
String name, signature, access; // Short cuts to constant pool return _cmp.hashCode(this);
// Get names from constant pool }
access = Utility.accessToString(access_flags);
access = access.equals("") ? "" : (access + " ");
signature = Utility.signatureToString(getSignature());
name = getName();
StringBuffer buf = new StringBuffer(64);
buf.append(access).append(signature).append(" ").append(name);
ConstantValue cv = getConstantValue();
if (cv != null) {
buf.append(" = ").append(cv);
}
for (int i = 0; i < attributes_count; i++) {
Attribute a = attributes[i];
if (!(a instanceof ConstantValue)) {
buf.append(" [").append(a.toString()).append("]");
}
}
return buf.toString();
}
/**
* @return deep copy of this field
*/
public final Field copy( ConstantPool _constant_pool ) {
return (Field) copy_(_constant_pool);
}
/**
* @return type of field
*/
public Type getType() {
return Type.getReturnType(getSignature());
}
/**
* @return Comparison strategy object
*/
public static BCELComparator getComparator() {
return _cmp;
}
/**
* @param comparator Comparison strategy object
*/
public static void setComparator( BCELComparator comparator ) {
_cmp = comparator;
}
/**
* Return value as defined by given BCELComparator strategy.
* By default two Field objects are said to be equal when
* their names and signatures are equal.
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals( Object obj ) {
return _cmp.equals(this, obj);
}
/**
* Return value as defined by given BCELComparator strategy.
* By default return the hashcode of the field's name XOR signature.
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return _cmp.hashCode(this);
}
} }

View File

@ -21,186 +21,190 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* Abstract super class for fields and methods. * Abstract super class for fields and methods.
* *
* @version $Id: FieldOrMethod.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: FieldOrMethod.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node { public abstract class FieldOrMethod extends AccessFlags implements Cloneable,
Node {
protected int name_index; // Points to field name in constant pool /**
protected int signature_index; // Points to encoded signature *
protected int attributes_count; // No. of attributes */
protected Attribute[] attributes; // Collection of attributes private static final long serialVersionUID = 1L;
protected ConstantPool constant_pool; protected int name_index; // Points to field name in constant pool
protected int signature_index; // Points to encoded signature
protected int attributes_count; // No. of attributes
protected Attribute[] attributes; // Collection of attributes
protected ConstantPool constant_pool;
FieldOrMethod() {
}
FieldOrMethod() { /**
} * Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
protected FieldOrMethod(FieldOrMethod c) {
this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), c
.getAttributes(), c.getConstantPool());
}
/**
* Construct object from file stream.
*
* @param file
* Input stream
* @throws IOException
* @throws ClassFormatException
*/
protected FieldOrMethod(DataInputStream file, ConstantPool constant_pool)
throws IOException, ClassFormatException {
this(file.readUnsignedShort(), file.readUnsignedShort(), file
.readUnsignedShort(), null, constant_pool);
attributes_count = file.readUnsignedShort();
attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
attributes[i] = Attribute.readAttribute(file, constant_pool);
}
}
/** /**
* Initialize from another object. Note that both objects use the same * @param access_flags
* references (shallow copy). Use clone() for a physical copy. * Access rights of method
*/ * @param name_index
protected FieldOrMethod(FieldOrMethod c) { * Points to field name in constant pool
this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c * @param signature_index
.getConstantPool()); * Points to encoded signature
} * @param attributes
* Collection of attributes
* @param constant_pool
* Array of constants
*/
protected FieldOrMethod(int access_flags, int name_index,
int signature_index, Attribute[] attributes,
ConstantPool constant_pool) {
this.access_flags = access_flags;
this.name_index = name_index;
this.signature_index = signature_index;
this.constant_pool = constant_pool;
setAttributes(attributes);
}
/**
* Dump object to file stream on binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
public final void dump(DataOutputStream file) throws IOException {
file.writeShort(access_flags);
file.writeShort(name_index);
file.writeShort(signature_index);
file.writeShort(attributes_count);
for (int i = 0; i < attributes_count; i++) {
attributes[i].dump(file);
}
}
/** /**
* Construct object from file stream. * @return Collection of object attributes.
* @param file Input stream */
* @throws IOException public final Attribute[] getAttributes() {
* @throws ClassFormatException return attributes;
*/ }
protected FieldOrMethod(DataInputStream file, ConstantPool constant_pool) throws IOException,
ClassFormatException {
this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null,
constant_pool);
attributes_count = file.readUnsignedShort();
attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
attributes[i] = Attribute.readAttribute(file, constant_pool);
}
}
/**
* @param attributes
* Collection of object attributes.
*/
public final void setAttributes(Attribute[] attributes) {
this.attributes = attributes;
attributes_count = (attributes == null) ? 0 : attributes.length;
}
/** /**
* @param access_flags Access rights of method * @return Constant pool used by this object.
* @param name_index Points to field name in constant pool */
* @param signature_index Points to encoded signature public final ConstantPool getConstantPool() {
* @param attributes Collection of attributes return constant_pool;
* @param constant_pool Array of constants }
*/
protected FieldOrMethod(int access_flags, int name_index, int signature_index,
Attribute[] attributes, ConstantPool constant_pool) {
this.access_flags = access_flags;
this.name_index = name_index;
this.signature_index = signature_index;
this.constant_pool = constant_pool;
setAttributes(attributes);
}
/**
* @param constant_pool
* Constant pool to be used for this object.
*/
public final void setConstantPool(ConstantPool constant_pool) {
this.constant_pool = constant_pool;
}
/** /**
* Dump object to file stream on binary format. * @return Index in constant pool of object's name.
* */
* @param file Output file stream public final int getNameIndex() {
* @throws IOException return name_index;
*/ }
public final void dump( DataOutputStream file ) throws IOException {
file.writeShort(access_flags);
file.writeShort(name_index);
file.writeShort(signature_index);
file.writeShort(attributes_count);
for (int i = 0; i < attributes_count; i++) {
attributes[i].dump(file);
}
}
/**
* @param name_index
* Index in constant pool of object's name.
*/
public final void setNameIndex(int name_index) {
this.name_index = name_index;
}
/** /**
* @return Collection of object attributes. * @return Index in constant pool of field signature.
*/ */
public final Attribute[] getAttributes() { public final int getSignatureIndex() {
return attributes; return signature_index;
} }
/**
* @param signature_index
* Index in constant pool of field signature.
*/
public final void setSignatureIndex(int signature_index) {
this.signature_index = signature_index;
}
/** /**
* @param attributes Collection of object attributes. * @return Name of object, i.e., method name or field name
*/ */
public final void setAttributes( Attribute[] attributes ) { public final String getName() {
this.attributes = attributes; ConstantUtf8 c;
attributes_count = (attributes == null) ? 0 : attributes.length; c = (ConstantUtf8) constant_pool.getConstant(name_index,
} Constants.CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return String representation of object's type signature (java style)
*/
public final String getSignature() {
ConstantUtf8 c;
c = (ConstantUtf8) constant_pool.getConstant(signature_index,
Constants.CONSTANT_Utf8);
return c.getBytes();
}
/** /**
* @return Constant pool used by this object. * @return deep copy of this field
*/ */
public final ConstantPool getConstantPool() { protected FieldOrMethod copy_(ConstantPool _constant_pool) {
return constant_pool; try {
} FieldOrMethod c = (FieldOrMethod) clone();
c.constant_pool = _constant_pool;
c.attributes = new Attribute[attributes_count];
/** for (int i = 0; i < attributes_count; i++) {
* @param constant_pool Constant pool to be used for this object. c.attributes[i] = attributes[i].copy(_constant_pool);
*/ }
public final void setConstantPool( ConstantPool constant_pool ) { return c;
this.constant_pool = constant_pool; } catch (CloneNotSupportedException e) {
} return null;
}
}
/**
* @return Index in constant pool of object's name.
*/
public final int getNameIndex() {
return name_index;
}
/**
* @param name_index Index in constant pool of object's name.
*/
public final void setNameIndex( int name_index ) {
this.name_index = name_index;
}
/**
* @return Index in constant pool of field signature.
*/
public final int getSignatureIndex() {
return signature_index;
}
/**
* @param signature_index Index in constant pool of field signature.
*/
public final void setSignatureIndex( int signature_index ) {
this.signature_index = signature_index;
}
/**
* @return Name of object, i.e., method name or field name
*/
public final String getName() {
ConstantUtf8 c;
c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return String representation of object's type signature (java style)
*/
public final String getSignature() {
ConstantUtf8 c;
c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return deep copy of this field
*/
protected FieldOrMethod copy_( ConstantPool _constant_pool ) {
try {
FieldOrMethod c = (FieldOrMethod) clone();
c.constant_pool = _constant_pool;
c.attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
c.attributes[i] = attributes[i].copy(_constant_pool);
}
return c;
} catch (CloneNotSupportedException e) {
return null;
}
}
} }

View File

@ -22,193 +22,194 @@ import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents a inner class attribute, i.e., the class * This class represents a inner class attribute, i.e., the class indices of the
* indices of the inner and outer classes, the name and the attributes * inner and outer classes, the name and the attributes of the inner class.
* of the inner class. *
*
* @version $Id: InnerClass.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: InnerClass.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see InnerClasses * @see InnerClasses
*/ */
public final class InnerClass implements Cloneable, Node, Serializable { public final class InnerClass implements Cloneable, Node, Serializable {
private int inner_class_index; /**
private int outer_class_index; *
private int inner_name_index; */
private int inner_access_flags; private static final long serialVersionUID = 1L;
private int inner_class_index;
private int outer_class_index;
private int inner_name_index;
private int inner_access_flags;
/**
* Initialize from another object.
*/
public InnerClass(InnerClass c) {
this(c.getInnerClassIndex(), c.getOuterClassIndex(), c
.getInnerNameIndex(), c.getInnerAccessFlags());
}
/** /**
* Initialize from another object. * Construct object from file stream.
*/ *
public InnerClass(InnerClass c) { * @param file
this(c.getInnerClassIndex(), c.getOuterClassIndex(), c.getInnerNameIndex(), c * Input stream
.getInnerAccessFlags()); * @throws IOException
} */
InnerClass(DataInputStream file) throws IOException {
this(file.readUnsignedShort(), file.readUnsignedShort(), file
.readUnsignedShort(), file.readUnsignedShort());
}
/**
* @param inner_class_index
* Class index in constant pool of inner class
* @param outer_class_index
* Class index in constant pool of outer class
* @param inner_name_index
* Name index in constant pool of inner class
* @param inner_access_flags
* Access flags of inner class
*/
public InnerClass(int inner_class_index, int outer_class_index,
int inner_name_index, int inner_access_flags) {
this.inner_class_index = inner_class_index;
this.outer_class_index = outer_class_index;
this.inner_name_index = inner_name_index;
this.inner_access_flags = inner_access_flags;
}
/** /**
* Construct object from file stream. * Called by objects that are traversing the nodes of the tree implicitely
* @param file Input stream * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @throws IOException * fields, attributes, etc. spawns a tree of objects.
*/ *
InnerClass(DataInputStream file) throws IOException { * @param v
this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file * Visitor object
.readUnsignedShort()); */
} @Override
public void accept(Visitor v) {
v.visitInnerClass(this);
}
/**
* Dump inner class attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
public final void dump(DataOutputStream file) throws IOException {
file.writeShort(inner_class_index);
file.writeShort(outer_class_index);
file.writeShort(inner_name_index);
file.writeShort(inner_access_flags);
}
/** /**
* @param inner_class_index Class index in constant pool of inner class * @return access flags of inner class.
* @param outer_class_index Class index in constant pool of outer class */
* @param inner_name_index Name index in constant pool of inner class public final int getInnerAccessFlags() {
* @param inner_access_flags Access flags of inner class return inner_access_flags;
*/ }
public InnerClass(int inner_class_index, int outer_class_index, int inner_name_index,
int inner_access_flags) {
this.inner_class_index = inner_class_index;
this.outer_class_index = outer_class_index;
this.inner_name_index = inner_name_index;
this.inner_access_flags = inner_access_flags;
}
/**
* @return class index of inner class.
*/
public final int getInnerClassIndex() {
return inner_class_index;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return name index of inner class.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final int getInnerNameIndex() {
* return inner_name_index;
* @param v Visitor object }
*/
public void accept( Visitor v ) {
v.visitInnerClass(this);
}
/**
* @return class index of outer class.
*/
public final int getOuterClassIndex() {
return outer_class_index;
}
/** /**
* Dump inner class attribute to file stream in binary format. * @param inner_access_flags
* * access flags for this inner class
* @param file Output file stream */
* @throws IOException public final void setInnerAccessFlags(int inner_access_flags) {
*/ this.inner_access_flags = inner_access_flags;
public final void dump( DataOutputStream file ) throws IOException { }
file.writeShort(inner_class_index);
file.writeShort(outer_class_index);
file.writeShort(inner_name_index);
file.writeShort(inner_access_flags);
}
/**
* @param inner_class_index
* index into the constant pool for this class
*/
public final void setInnerClassIndex(int inner_class_index) {
this.inner_class_index = inner_class_index;
}
/** /**
* @return access flags of inner class. * @param inner_name_index
*/ * index into the constant pool for this class's name
public final int getInnerAccessFlags() { */
return inner_access_flags; public final void setInnerNameIndex(int inner_name_index) {
} this.inner_name_index = inner_name_index;
}
/**
* @param outer_class_index
* index into the constant pool for the owning class
*/
public final void setOuterClassIndex(int outer_class_index) {
this.outer_class_index = outer_class_index;
}
/** /**
* @return class index of inner class. * @return String representation.
*/ */
public final int getInnerClassIndex() { @Override
return inner_class_index; public final String toString() {
} return "InnerClass(" + inner_class_index + ", " + outer_class_index
+ ", " + inner_name_index + ", " + inner_access_flags + ")";
}
/**
* @return Resolved string representation
*/
public final String toString(ConstantPool constant_pool) {
String inner_class_name, outer_class_name, inner_name, access;
inner_class_name = constant_pool.getConstantString(inner_class_index,
Constants.CONSTANT_Class);
inner_class_name = Utility.compactClassName(inner_class_name);
if (outer_class_index != 0) {
outer_class_name = constant_pool.getConstantString(
outer_class_index, Constants.CONSTANT_Class);
outer_class_name = Utility.compactClassName(outer_class_name);
} else {
outer_class_name = "<not a member>";
}
if (inner_name_index != 0) {
inner_name = ((ConstantUtf8) constant_pool.getConstant(
inner_name_index, Constants.CONSTANT_Utf8)).getBytes();
} else {
inner_name = "<anonymous>";
}
access = Utility.accessToString(inner_access_flags, true);
access = access.equals("") ? "" : (access + " ");
return "InnerClass:" + access + inner_class_name + "(\""
+ outer_class_name + "\", \"" + inner_name + "\")";
}
/** /**
* @return name index of inner class. * @return deep copy of this object
*/ */
public final int getInnerNameIndex() { public InnerClass copy() {
return inner_name_index; try {
} return (InnerClass) clone();
} catch (CloneNotSupportedException e) {
}
/** return null;
* @return class index of outer class. }
*/
public final int getOuterClassIndex() {
return outer_class_index;
}
/**
* @param inner_access_flags access flags for this inner class
*/
public final void setInnerAccessFlags( int inner_access_flags ) {
this.inner_access_flags = inner_access_flags;
}
/**
* @param inner_class_index index into the constant pool for this class
*/
public final void setInnerClassIndex( int inner_class_index ) {
this.inner_class_index = inner_class_index;
}
/**
* @param inner_name_index index into the constant pool for this class's name
*/
public final void setInnerNameIndex( int inner_name_index ) {
this.inner_name_index = inner_name_index;
}
/**
* @param outer_class_index index into the constant pool for the owning class
*/
public final void setOuterClassIndex( int outer_class_index ) {
this.outer_class_index = outer_class_index;
}
/**
* @return String representation.
*/
public final String toString() {
return "InnerClass(" + inner_class_index + ", " + outer_class_index + ", "
+ inner_name_index + ", " + inner_access_flags + ")";
}
/**
* @return Resolved string representation
*/
public final String toString( ConstantPool constant_pool ) {
String inner_class_name, outer_class_name, inner_name, access;
inner_class_name = constant_pool.getConstantString(inner_class_index,
Constants.CONSTANT_Class);
inner_class_name = Utility.compactClassName(inner_class_name);
if (outer_class_index != 0) {
outer_class_name = constant_pool.getConstantString(outer_class_index,
Constants.CONSTANT_Class);
outer_class_name = Utility.compactClassName(outer_class_name);
} else {
outer_class_name = "<not a member>";
}
if (inner_name_index != 0) {
inner_name = ((ConstantUtf8) constant_pool.getConstant(inner_name_index,
Constants.CONSTANT_Utf8)).getBytes();
} else {
inner_name = "<anonymous>";
}
access = Utility.accessToString(inner_access_flags, true);
access = access.equals("") ? "" : (access + " ");
return "InnerClass:" + access + inner_class_name + "(\"" + outer_class_name + "\", \""
+ inner_name + "\")";
}
/**
* @return deep copy of this object
*/
public InnerClass copy() {
try {
return (InnerClass) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
} }

View File

@ -22,129 +22,139 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from <em>Attribute</em> and denotes that this class * This class is derived from <em>Attribute</em> and denotes that this class is
* is an Inner class of another. * an Inner class of another. to the source file of this class. It is
* to the source file of this class. * instantiated from the <em>Attribute.readAttribute()</em> method.
* It is instantiated from the <em>Attribute.readAttribute()</em> method. *
*
* @version $Id: InnerClasses.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: InnerClasses.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute * @see Attribute
*/ */
public final class InnerClasses extends Attribute { public final class InnerClasses extends Attribute {
private InnerClass[] inner_classes; /**
private int number_of_classes; *
*/
private static final long serialVersionUID = 1L;
private InnerClass[] inner_classes;
private int number_of_classes;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public InnerClasses(InnerClasses c) {
this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c
.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * @param name_index
* references (shallow copy). Use clone() for a physical copy. * Index in constant pool to CONSTANT_Utf8
*/ * @param length
public InnerClasses(InnerClasses c) { * Content length in bytes
this(c.getNameIndex(), c.getLength(), c.getInnerClasses(), c.getConstantPool()); * @param inner_classes
} * array of inner classes attributes
* @param constant_pool
* Array of constants
*/
public InnerClasses(int name_index, int length, InnerClass[] inner_classes,
ConstantPool constant_pool) {
super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool);
setInnerClasses(inner_classes);
}
/**
* Construct object from file stream.
*
* @param name_index
* Index in constant pool to CONSTANT_Utf8
* @param length
* Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
InnerClasses(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, (InnerClass[]) null, constant_pool);
number_of_classes = file.readUnsignedShort();
inner_classes = new InnerClass[number_of_classes];
for (int i = 0; i < number_of_classes; i++) {
inner_classes[i] = new InnerClass(file);
}
}
/** /**
* @param name_index Index in constant pool to CONSTANT_Utf8 * Called by objects that are traversing the nodes of the tree implicitely
* @param length Content length in bytes * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param inner_classes array of inner classes attributes * fields, attributes, etc. spawns a tree of objects.
* @param constant_pool Array of constants *
*/ * @param v
public InnerClasses(int name_index, int length, InnerClass[] inner_classes, * Visitor object
ConstantPool constant_pool) { */
super(Constants.ATTR_INNER_CLASSES, name_index, length, constant_pool); @Override
setInnerClasses(inner_classes); public void accept(Visitor v) {
} v.visitInnerClasses(this);
}
/**
* Dump source file attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(number_of_classes);
for (int i = 0; i < number_of_classes; i++) {
inner_classes[i].dump(file);
}
}
/** /**
* Construct object from file stream. * @return array of inner class "records"
* */
* @param name_index Index in constant pool to CONSTANT_Utf8 public final InnerClass[] getInnerClasses() {
* @param length Content length in bytes return inner_classes;
* @param file Input stream }
* @param constant_pool Array of constants
* @throws IOException
*/
InnerClasses(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, (InnerClass[]) null, constant_pool);
number_of_classes = file.readUnsignedShort();
inner_classes = new InnerClass[number_of_classes];
for (int i = 0; i < number_of_classes; i++) {
inner_classes[i] = new InnerClass(file);
}
}
/**
* @param inner_classes
* the array of inner classes
*/
public final void setInnerClasses(InnerClass[] inner_classes) {
this.inner_classes = inner_classes;
number_of_classes = (inner_classes == null) ? 0 : inner_classes.length;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object StringBuffer buf = new StringBuffer();
*/ for (int i = 0; i < number_of_classes; i++) {
public void accept( Visitor v ) { buf.append(inner_classes[i].toString(constant_pool)).append("\n");
v.visitInnerClasses(this); }
} return buf.toString();
}
/**
/** * @return deep copy of this attribute
* Dump source file attribute to file stream in binary format. */
* @Override
* @param file Output file stream public Attribute copy(ConstantPool _constant_pool) {
* @throws IOException InnerClasses c = (InnerClasses) clone();
*/ c.inner_classes = new InnerClass[number_of_classes];
public final void dump( DataOutputStream file ) throws IOException { for (int i = 0; i < number_of_classes; i++) {
super.dump(file); c.inner_classes[i] = inner_classes[i].copy();
file.writeShort(number_of_classes); }
for (int i = 0; i < number_of_classes; i++) { c.constant_pool = _constant_pool;
inner_classes[i].dump(file); return c;
} }
}
/**
* @return array of inner class "records"
*/
public final InnerClass[] getInnerClasses() {
return inner_classes;
}
/**
* @param inner_classes the array of inner classes
*/
public final void setInnerClasses( InnerClass[] inner_classes ) {
this.inner_classes = inner_classes;
number_of_classes = (inner_classes == null) ? 0 : inner_classes.length;
}
/**
* @return String representation.
*/
public final String toString() {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < number_of_classes; i++) {
buf.append(inner_classes[i].toString(constant_pool)).append("\n");
}
return buf.toString();
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
InnerClasses c = (InnerClasses) clone();
c.inner_classes = new InnerClass[number_of_classes];
for (int i = 0; i < number_of_classes; i++) {
c.inner_classes[i] = inner_classes[i].copy();
}
c.constant_pool = _constant_pool;
return c;
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -23,119 +23,122 @@ import java.io.Serializable;
/** /**
* This class represents a (PC offset, line number) pair, i.e., a line number in * This class represents a (PC offset, line number) pair, i.e., a line number in
* the source that corresponds to a relative address in the byte code. This * the source that corresponds to a relative address in the byte code. This is
* is used for debugging purposes. * used for debugging purposes.
* *
* @version $Id: LineNumber.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: LineNumber.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see LineNumberTable * @see LineNumberTable
*/ */
public final class LineNumber implements Cloneable, Node, Serializable { public final class LineNumber implements Cloneable, Node, Serializable {
private int start_pc; // Program Counter (PC) corresponds to line /**
private int line_number; // number in source file *
*/
private static final long serialVersionUID = 1L;
private int start_pc; // Program Counter (PC) corresponds to line
private int line_number; // number in source file
/**
* Initialize from another object.
*/
public LineNumber(LineNumber c) {
this(c.getStartPC(), c.getLineNumber());
}
/** /**
* Initialize from another object. * Construct object from file stream.
*/ *
public LineNumber(LineNumber c) { * @param file
this(c.getStartPC(), c.getLineNumber()); * Input stream
} * @throws IOException
*/
LineNumber(DataInputStream file) throws IOException {
this(file.readUnsignedShort(), file.readUnsignedShort());
}
/**
* @param start_pc
* Program Counter (PC) corresponds to
* @param line_number
* line number in source file
*/
public LineNumber(int start_pc, int line_number) {
this.start_pc = start_pc;
this.line_number = line_number;
}
/** /**
* Construct object from file stream. * Called by objects that are traversing the nodes of the tree implicitely
* @param file Input stream * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @throws IOException * fields, attributes, etc. spawns a tree of objects.
*/ *
LineNumber(DataInputStream file) throws IOException { * @param v
this(file.readUnsignedShort(), file.readUnsignedShort()); * Visitor object
} */
@Override
public void accept(Visitor v) {
v.visitLineNumber(this);
}
/**
* Dump line number/pc pair to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
public final void dump(DataOutputStream file) throws IOException {
file.writeShort(start_pc);
file.writeShort(line_number);
}
/** /**
* @param start_pc Program Counter (PC) corresponds to * @return Corresponding source line
* @param line_number line number in source file */
*/ public final int getLineNumber() {
public LineNumber(int start_pc, int line_number) { return line_number;
this.start_pc = start_pc; }
this.line_number = line_number;
}
/**
* @return PC in code
*/
public final int getStartPC() {
return start_pc;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @param line_number
* defined by the contents of a Java class. I.e., the hierarchy of methods, * the source line number
* fields, attributes, etc. spawns a tree of objects. */
* public final void setLineNumber(int line_number) {
* @param v Visitor object this.line_number = line_number;
*/ }
public void accept( Visitor v ) {
v.visitLineNumber(this);
}
/**
* @param start_pc
* the pc for this line number
*/
public final void setStartPC(int start_pc) {
this.start_pc = start_pc;
}
/** /**
* Dump line number/pc pair to file stream in binary format. * @return String representation
* */
* @param file Output file stream @Override
* @throws IOException public final String toString() {
*/ return "LineNumber(" + start_pc + ", " + line_number + ")";
public final void dump( DataOutputStream file ) throws IOException { }
file.writeShort(start_pc);
file.writeShort(line_number);
}
/**
/** * @return deep copy of this object
* @return Corresponding source line */
*/ public LineNumber copy() {
public final int getLineNumber() { try {
return line_number; return (LineNumber) clone();
} } catch (CloneNotSupportedException e) {
}
return null;
/** }
* @return PC in code
*/
public final int getStartPC() {
return start_pc;
}
/**
* @param line_number the source line number
*/
public final void setLineNumber( int line_number ) {
this.line_number = line_number;
}
/**
* @param start_pc the pc for this line number
*/
public final void setStartPC( int start_pc ) {
this.start_pc = start_pc;
}
/**
* @return String representation
*/
public final String toString() {
return "LineNumber(" + start_pc + ", " + line_number + ")";
}
/**
* @return deep copy of this object
*/
public LineNumber copy() {
try {
return (LineNumber) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
} }

View File

@ -22,187 +22,202 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents a table of line numbers for debugging * This class represents a table of line numbers for debugging purposes. This
* purposes. This attribute is used by the <em>Code</em> attribute. It * attribute is used by the <em>Code</em> attribute. It contains pairs of PCs
* contains pairs of PCs and line numbers. * and line numbers.
* *
* @version $Id: LineNumberTable.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: LineNumberTable.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code * @see Code
* @see LineNumber * @see LineNumber
*/ */
public final class LineNumberTable extends Attribute { public final class LineNumberTable extends Attribute {
private int line_number_table_length; /**
private LineNumber[] line_number_table; // Table of line/numbers pairs *
*/
private static final long serialVersionUID = 1L;
private int line_number_table_length;
private LineNumber[] line_number_table; // Table of line/numbers pairs
/*
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use copy() for a physical copy.
*/
public LineNumberTable(LineNumberTable c) {
this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c
.getConstantPool());
}
/* /*
* Initialize from another object. Note that both objects use the same * @param name_index Index of name
* references (shallow copy). Use copy() for a physical copy. *
*/ * @param length Content length in bytes
public LineNumberTable(LineNumberTable c) { *
this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool()); * @param line_number_table Table of line/numbers pairs
} *
* @param constant_pool Array of constants
*/
public LineNumberTable(int name_index, int length,
LineNumber[] line_number_table, ConstantPool constant_pool) {
super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length,
constant_pool);
setLineNumberTable(line_number_table);
}
/**
* Construct object from file stream.
*
* @param name_index
* Index of name
* @param length
* Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
LineNumberTable(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, (LineNumber[]) null, constant_pool);
line_number_table_length = (file.readUnsignedShort());
line_number_table = new LineNumber[line_number_table_length];
for (int i = 0; i < line_number_table_length; i++) {
line_number_table[i] = new LineNumber(file);
}
}
/* /**
* @param name_index Index of name * Called by objects that are traversing the nodes of the tree implicitely
* @param length Content length in bytes * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param line_number_table Table of line/numbers pairs * fields, attributes, etc. spawns a tree of objects.
* @param constant_pool Array of constants *
*/ * @param v
public LineNumberTable(int name_index, int length, LineNumber[] line_number_table, * Visitor object
ConstantPool constant_pool) { */
super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool); @Override
setLineNumberTable(line_number_table); public void accept(Visitor v) {
} v.visitLineNumberTable(this);
}
/**
* Dump line number table attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(line_number_table_length);
for (int i = 0; i < line_number_table_length; i++) {
line_number_table[i].dump(file);
}
}
/** /**
* Construct object from file stream. * @return Array of (pc offset, line number) pairs.
* @param name_index Index of name */
* @param length Content length in bytes public final LineNumber[] getLineNumberTable() {
* @param file Input stream return line_number_table;
* @param constant_pool Array of constants }
* @throws IOException
*/
LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, (LineNumber[]) null, constant_pool);
line_number_table_length = (file.readUnsignedShort());
line_number_table = new LineNumber[line_number_table_length];
for (int i = 0; i < line_number_table_length; i++) {
line_number_table[i] = new LineNumber(file);
}
}
/**
* @param line_number_table
* the line number entries for this table
*/
public final void setLineNumberTable(LineNumber[] line_number_table) {
this.line_number_table = line_number_table;
line_number_table_length = (line_number_table == null) ? 0
: line_number_table.length;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object StringBuffer buf = new StringBuffer();
*/ StringBuffer line = new StringBuffer();
public void accept( Visitor v ) { String newLine = System.getProperty("line.separator", "\n");
v.visitLineNumberTable(this); for (int i = 0; i < line_number_table_length; i++) {
} line.append(line_number_table[i].toString());
if (i < line_number_table_length - 1) {
line.append(", ");
}
if (line.length() > 72) {
line.append(newLine);
buf.append(line.toString());
line.setLength(0);
}
}
buf.append(line);
return buf.toString();
}
/**
* Map byte code positions to source code lines.
*
* @param pos
* byte code offset
* @return corresponding line in source code
*/
public int getSourceLine(int pos) {
int l = 0, r = line_number_table_length - 1;
if (r < 0) {
return -1;
}
int min_index = -1, min = -1;
/*
* Do a binary search since the array is ordered.
*/
do {
int i = (l + r) / 2;
int j = line_number_table[i].getStartPC();
if (j == pos) {
return line_number_table[i].getLineNumber();
} else if (pos < j) {
r = i - 1;
} else {
l = i + 1;
}
/*
* If exact match can't be found (which is the most common case)
* return the line number that corresponds to the greatest index
* less than pos.
*/
if (j < pos && j > min) {
min = j;
min_index = i;
}
} while (l <= r);
/*
* It's possible that we did not find any valid entry for the bytecode
* offset we were looking for.
*/
if (min_index < 0) {
return -1;
}
return line_number_table[min_index].getLineNumber();
}
/** /**
* Dump line number table attribute to file stream in binary format. * @return deep copy of this attribute
* */
* @param file Output file stream @Override
* @throws IOException public Attribute copy(ConstantPool _constant_pool) {
*/ LineNumberTable c = (LineNumberTable) clone();
public final void dump( DataOutputStream file ) throws IOException { c.line_number_table = new LineNumber[line_number_table_length];
super.dump(file); for (int i = 0; i < line_number_table_length; i++) {
file.writeShort(line_number_table_length); c.line_number_table[i] = line_number_table[i].copy();
for (int i = 0; i < line_number_table_length; i++) { }
line_number_table[i].dump(file); c.constant_pool = _constant_pool;
} return c;
} }
public final int getTableLength() {
/** return line_number_table_length;
* @return Array of (pc offset, line number) pairs. }
*/
public final LineNumber[] getLineNumberTable() {
return line_number_table;
}
/**
* @param line_number_table the line number entries for this table
*/
public final void setLineNumberTable( LineNumber[] line_number_table ) {
this.line_number_table = line_number_table;
line_number_table_length = (line_number_table == null) ? 0 : line_number_table.length;
}
/**
* @return String representation.
*/
public final String toString() {
StringBuffer buf = new StringBuffer();
StringBuffer line = new StringBuffer();
String newLine = System.getProperty("line.separator", "\n");
for (int i = 0; i < line_number_table_length; i++) {
line.append(line_number_table[i].toString());
if (i < line_number_table_length - 1) {
line.append(", ");
}
if (line.length() > 72) {
line.append(newLine);
buf.append(line.toString());
line.setLength(0);
}
}
buf.append(line);
return buf.toString();
}
/**
* Map byte code positions to source code lines.
*
* @param pos byte code offset
* @return corresponding line in source code
*/
public int getSourceLine( int pos ) {
int l = 0, r = line_number_table_length - 1;
if (r < 0) {
return -1;
}
int min_index = -1, min = -1;
/* Do a binary search since the array is ordered.
*/
do {
int i = (l + r) / 2;
int j = line_number_table[i].getStartPC();
if (j == pos) {
return line_number_table[i].getLineNumber();
} else if (pos < j) {
r = i - 1;
} else {
l = i + 1;
}
/* If exact match can't be found (which is the most common case)
* return the line number that corresponds to the greatest index less
* than pos.
*/
if (j < pos && j > min) {
min = j;
min_index = i;
}
} while (l <= r);
/* It's possible that we did not find any valid entry for the bytecode
* offset we were looking for.
*/
if (min_index < 0) {
return -1;
}
return line_number_table[min_index].getLineNumber();
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
LineNumberTable c = (LineNumberTable) clone();
c.line_number_table = new LineNumber[line_number_table_length];
for (int i = 0; i < line_number_table_length; i++) {
c.line_number_table[i] = line_number_table[i].copy();
}
c.constant_pool = _constant_pool;
return c;
}
public final int getTableLength() {
return line_number_table_length;
}
} }

View File

@ -25,224 +25,232 @@ import org.apache.bcel.Constants;
/** /**
* This class represents a local variable within a method. It contains its * This class represents a local variable within a method. It contains its
* scope, name, signature and index on the method's frame. * scope, name, signature and index on the method's frame.
* *
* @version $Id: LocalVariable.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: LocalVariable.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see LocalVariableTable * @see LocalVariableTable
*/ */
public final class LocalVariable implements Constants, Cloneable, Node, Serializable { public final class LocalVariable implements Constants, Cloneable, Node,
Serializable {
private int start_pc; // Range in which the variable is valid /**
private int length; *
private int name_index; // Index in constant pool of variable name */
private int signature_index; // Index of variable signature private static final long serialVersionUID = 1L;
private int index; /* Variable is `index'th local variable on private int start_pc; // Range in which the variable is valid
* this method's frame. private int length;
*/ private int name_index; // Index in constant pool of variable name
private ConstantPool constant_pool; private int signature_index; // Index of variable signature
private int index; /*
* Variable is `index'th local variable on this method's
* frame.
*/
private ConstantPool constant_pool;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use copy() for a physical copy.
*/
public LocalVariable(LocalVariable c) {
this(c.getStartPC(), c.getLength(), c.getNameIndex(), c
.getSignatureIndex(), c.getIndex(), c.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * Construct object from file stream.
* references (shallow copy). Use copy() for a physical copy. *
*/ * @param file
public LocalVariable(LocalVariable c) { * Input stream
this(c.getStartPC(), c.getLength(), c.getNameIndex(), c.getSignatureIndex(), c.getIndex(), * @throws IOException
c.getConstantPool()); */
} LocalVariable(DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(file.readUnsignedShort(), file.readUnsignedShort(), file
.readUnsignedShort(), file.readUnsignedShort(), file
.readUnsignedShort(), constant_pool);
}
/**
* @param start_pc
* Range in which the variable
* @param length
* ... is valid
* @param name_index
* Index in constant pool of variable name
* @param signature_index
* Index of variable's signature
* @param index
* Variable is `index'th local variable on the method's frame
* @param constant_pool
* Array of constants
*/
public LocalVariable(int start_pc, int length, int name_index,
int signature_index, int index, ConstantPool constant_pool) {
this.start_pc = start_pc;
this.length = length;
this.name_index = name_index;
this.signature_index = signature_index;
this.index = index;
this.constant_pool = constant_pool;
}
/** /**
* Construct object from file stream. * Called by objects that are traversing the nodes of the tree implicitely
* @param file Input stream * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @throws IOException * fields, attributes, etc. spawns a tree of objects.
*/ *
LocalVariable(DataInputStream file, ConstantPool constant_pool) throws IOException { * @param v
this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file * Visitor object
.readUnsignedShort(), file.readUnsignedShort(), constant_pool); */
} @Override
public void accept(Visitor v) {
v.visitLocalVariable(this);
}
/**
* Dump local variable to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
public final void dump(DataOutputStream file) throws IOException {
file.writeShort(start_pc);
file.writeShort(length);
file.writeShort(name_index);
file.writeShort(signature_index);
file.writeShort(index);
}
/** /**
* @param start_pc Range in which the variable * @return Constant pool used by this object.
* @param length ... is valid */
* @param name_index Index in constant pool of variable name public final ConstantPool getConstantPool() {
* @param signature_index Index of variable's signature return constant_pool;
* @param index Variable is `index'th local variable on the method's frame }
* @param constant_pool Array of constants
*/
public LocalVariable(int start_pc, int length, int name_index, int signature_index, int index,
ConstantPool constant_pool) {
this.start_pc = start_pc;
this.length = length;
this.name_index = name_index;
this.signature_index = signature_index;
this.index = index;
this.constant_pool = constant_pool;
}
/**
* @return Variable is valid within getStartPC() .. getStartPC()+getLength()
*/
public final int getLength() {
return length;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return Variable name.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final String getName() {
* ConstantUtf8 c;
* @param v Visitor object c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8);
*/ return c.getBytes();
public void accept( Visitor v ) { }
v.visitLocalVariable(this);
}
/**
* @return Index in constant pool of variable name.
*/
public final int getNameIndex() {
return name_index;
}
/** /**
* Dump local variable to file stream in binary format. * @return Signature.
* */
* @param file Output file stream public final String getSignature() {
* @throws IOException ConstantUtf8 c;
*/ c = (ConstantUtf8) constant_pool.getConstant(signature_index,
public final void dump( DataOutputStream file ) throws IOException { CONSTANT_Utf8);
file.writeShort(start_pc); return c.getBytes();
file.writeShort(length); }
file.writeShort(name_index);
file.writeShort(signature_index);
file.writeShort(index);
}
/**
* @return Index in constant pool of variable signature.
*/
public final int getSignatureIndex() {
return signature_index;
}
/** /**
* @return Constant pool used by this object. * @return index of register where variable is stored
*/ */
public final ConstantPool getConstantPool() { public final int getIndex() {
return constant_pool; return index;
} }
/**
* @return Start of range where he variable is valid
*/
public final int getStartPC() {
return start_pc;
}
/** /**
* @return Variable is valid within getStartPC() .. getStartPC()+getLength() * @param constant_pool
*/ * Constant pool to be used for this object.
public final int getLength() { */
return length; public final void setConstantPool(ConstantPool constant_pool) {
} this.constant_pool = constant_pool;
}
/**
* @param length
* the length of this local variable
*/
public final void setLength(int length) {
this.length = length;
}
/** /**
* @return Variable name. * @param name_index
*/ * the index into the constant pool for the name of this variable
public final String getName() { */
ConstantUtf8 c; public final void setNameIndex(int name_index) {
c = (ConstantUtf8) constant_pool.getConstant(name_index, CONSTANT_Utf8); this.name_index = name_index;
return c.getBytes(); }
}
/**
* @param signature_index
* the index into the constant pool for the signature of this
* variable
*/
public final void setSignatureIndex(int signature_index) {
this.signature_index = signature_index;
}
/** /**
* @return Index in constant pool of variable name. * @param index
*/ * the index in the local variable table of this variable
public final int getNameIndex() { */
return name_index; public final void setIndex(int index) {
} this.index = index;
}
/**
* @param start_pc
* Specify range where the local variable is valid.
*/
public final void setStartPC(int start_pc) {
this.start_pc = start_pc;
}
/** /**
* @return Signature. * @return string representation.
*/ */
public final String getSignature() { @Override
ConstantUtf8 c; public final String toString() {
c = (ConstantUtf8) constant_pool.getConstant(signature_index, CONSTANT_Utf8); String name = getName(), signature = Utility
return c.getBytes(); .signatureToString(getSignature());
} return "LocalVariable(start_pc = " + start_pc + ", length = " + length
+ ", index = " + index + ":" + signature + " " + name + ")";
}
/**
/** * @return deep copy of this object
* @return Index in constant pool of variable signature. */
*/ public LocalVariable copy() {
public final int getSignatureIndex() { try {
return signature_index; return (LocalVariable) clone();
} } catch (CloneNotSupportedException e) {
}
return null;
/** }
* @return index of register where variable is stored
*/
public final int getIndex() {
return index;
}
/**
* @return Start of range where he variable is valid
*/
public final int getStartPC() {
return start_pc;
}
/**
* @param constant_pool Constant pool to be used for this object.
*/
public final void setConstantPool( ConstantPool constant_pool ) {
this.constant_pool = constant_pool;
}
/**
* @param length the length of this local variable
*/
public final void setLength( int length ) {
this.length = length;
}
/**
* @param name_index the index into the constant pool for the name of this variable
*/
public final void setNameIndex( int name_index ) {
this.name_index = name_index;
}
/**
* @param signature_index the index into the constant pool for the signature of this variable
*/
public final void setSignatureIndex( int signature_index ) {
this.signature_index = signature_index;
}
/**
* @param index the index in the local variable table of this variable
*/
public final void setIndex( int index ) {
this.index = index;
}
/**
* @param start_pc Specify range where the local variable is valid.
*/
public final void setStartPC( int start_pc ) {
this.start_pc = start_pc;
}
/**
* @return string representation.
*/
public final String toString() {
String name = getName(), signature = Utility.signatureToString(getSignature());
return "LocalVariable(start_pc = " + start_pc + ", length = " + length + ", index = "
+ index + ":" + signature + " " + name + ")";
}
/**
* @return deep copy of this object
*/
public LocalVariable copy() {
try {
return (LocalVariable) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
} }

View File

@ -22,176 +22,187 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents colection of local variables in a * This class represents colection of local variables in a method. This
* method. This attribute is contained in the <em>Code</em> attribute. * attribute is contained in the <em>Code</em> attribute.
* *
* @version $Id: LocalVariableTable.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: LocalVariableTable.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code * @see Code
* @see LocalVariable * @see LocalVariable
*/ */
public class LocalVariableTable extends Attribute { public class LocalVariableTable extends Attribute {
private int local_variable_table_length; // Table of local /**
private LocalVariable[] local_variable_table; // variables *
*/
private static final long serialVersionUID = 1L;
private int local_variable_table_length; // Table of local
private LocalVariable[] local_variable_table; // variables
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use copy() for a physical copy.
*/
public LocalVariableTable(LocalVariableTable c) {
this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c
.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * @param name_index
* references (shallow copy). Use copy() for a physical copy. * Index in constant pool to `LocalVariableTable'
*/ * @param length
public LocalVariableTable(LocalVariableTable c) { * Content length in bytes
this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(), c.getConstantPool()); * @param local_variable_table
} * Table of local variables
* @param constant_pool
* Array of constants
*/
public LocalVariableTable(int name_index, int length,
LocalVariable[] local_variable_table, ConstantPool constant_pool) {
super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length,
constant_pool);
setLocalVariableTable(local_variable_table);
}
/**
* Construct object from file stream.
*
* @param name_index
* Index in constant pool
* @param length
* Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
LocalVariableTable(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, (LocalVariable[]) null, constant_pool);
local_variable_table_length = (file.readUnsignedShort());
local_variable_table = new LocalVariable[local_variable_table_length];
for (int i = 0; i < local_variable_table_length; i++) {
local_variable_table[i] = new LocalVariable(file, constant_pool);
}
}
/** /**
* @param name_index Index in constant pool to `LocalVariableTable' * Called by objects that are traversing the nodes of the tree implicitely
* @param length Content length in bytes * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param local_variable_table Table of local variables * fields, attributes, etc. spawns a tree of objects.
* @param constant_pool Array of constants *
*/ * @param v
public LocalVariableTable(int name_index, int length, LocalVariable[] local_variable_table, * Visitor object
ConstantPool constant_pool) { */
super(Constants.ATTR_LOCAL_VARIABLE_TABLE, name_index, length, constant_pool); @Override
setLocalVariableTable(local_variable_table); public void accept(Visitor v) {
} v.visitLocalVariableTable(this);
}
/**
* Dump local variable table attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(local_variable_table_length);
for (int i = 0; i < local_variable_table_length; i++) {
local_variable_table[i].dump(file);
}
}
/** /**
* Construct object from file stream. * @return Array of local variables of method.
* @param name_index Index in constant pool */
* @param length Content length in bytes public final LocalVariable[] getLocalVariableTable() {
* @param file Input stream return local_variable_table;
* @param constant_pool Array of constants }
* @throws IOException
*/
LocalVariableTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, (LocalVariable[]) null, constant_pool);
local_variable_table_length = (file.readUnsignedShort());
local_variable_table = new LocalVariable[local_variable_table_length];
for (int i = 0; i < local_variable_table_length; i++) {
local_variable_table[i] = new LocalVariable(file, constant_pool);
}
}
/**
* @return first matching variable using index
*
* @param index
* the variable slot
*
* @return the first LocalVariable that matches the slot or null if not
* found
*
*/
public final LocalVariable getLocalVariable(int index) {
for (int i = 0; i < local_variable_table_length; i++) {
if (local_variable_table[i].getIndex() == index) {
return local_variable_table[i];
}
}
return null;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return matching variable using index when variable is used at supplied
* defined by the contents of a Java class. I.e., the hierarchy of methods, * pc
* fields, attributes, etc. spawns a tree of objects. *
* * @param index
* @param v Visitor object * the variable slot
*/ * @param pc
public void accept( Visitor v ) { * the current pc that this variable is alive
v.visitLocalVariableTable(this); *
} * @return the LocalVariable that matches or null if not found
*/
public final LocalVariable getLocalVariable(int index, int pc) {
for (int i = 0; i < local_variable_table_length; i++) {
if (local_variable_table[i].getIndex() == index) {
int start_pc = local_variable_table[i].getStartPC();
int end_pc = start_pc + local_variable_table[i].getLength();
if ((pc >= start_pc) && (pc < end_pc)) {
return local_variable_table[i];
}
}
}
return null;
}
public final void setLocalVariableTable(LocalVariable[] local_variable_table) {
this.local_variable_table = local_variable_table;
local_variable_table_length = (local_variable_table == null) ? 0
: local_variable_table.length;
}
/** /**
* Dump local variable table attribute to file stream in binary format. * @return String representation.
* */
* @param file Output file stream @Override
* @throws IOException public final String toString() {
*/ StringBuffer buf = new StringBuffer("");
public final void dump( DataOutputStream file ) throws IOException { for (int i = 0; i < local_variable_table_length; i++) {
super.dump(file); buf.append(local_variable_table[i].toString());
file.writeShort(local_variable_table_length); if (i < local_variable_table_length - 1) {
for (int i = 0; i < local_variable_table_length; i++) { buf.append('\n');
local_variable_table[i].dump(file); }
} }
} return buf.toString();
}
/**
* @return deep copy of this attribute
*/
@Override
public Attribute copy(ConstantPool _constant_pool) {
LocalVariableTable c = (LocalVariableTable) clone();
c.local_variable_table = new LocalVariable[local_variable_table_length];
for (int i = 0; i < local_variable_table_length; i++) {
c.local_variable_table[i] = local_variable_table[i].copy();
}
c.constant_pool = _constant_pool;
return c;
}
/** public final int getTableLength() {
* @return Array of local variables of method. return local_variable_table_length;
*/ }
public final LocalVariable[] getLocalVariableTable() {
return local_variable_table;
}
/**
* @return first matching variable using index
*
* @param index the variable slot
*
* @return the first LocalVariable that matches the slot or null if not found
*
* @deprecated since 5.2 because multiple variables can share the
* same slot, use getLocalVariable(int index, int pc) instead.
*/
public final LocalVariable getLocalVariable( int index ) {
for (int i = 0; i < local_variable_table_length; i++) {
if (local_variable_table[i].getIndex() == index) {
return local_variable_table[i];
}
}
return null;
}
/**
* @return matching variable using index when variable is used at supplied pc
*
* @param index the variable slot
* @param pc the current pc that this variable is alive
*
* @return the LocalVariable that matches or null if not found
*/
public final LocalVariable getLocalVariable( int index, int pc ) {
for (int i = 0; i < local_variable_table_length; i++) {
if (local_variable_table[i].getIndex() == index) {
int start_pc = local_variable_table[i].getStartPC();
int end_pc = start_pc + local_variable_table[i].getLength();
if ((pc >= start_pc) && (pc < end_pc)) {
return local_variable_table[i];
}
}
}
return null;
}
public final void setLocalVariableTable( LocalVariable[] local_variable_table ) {
this.local_variable_table = local_variable_table;
local_variable_table_length = (local_variable_table == null)
? 0
: local_variable_table.length;
}
/**
* @return String representation.
*/
public final String toString() {
StringBuffer buf = new StringBuffer("");
for (int i = 0; i < local_variable_table_length; i++) {
buf.append(local_variable_table[i].toString());
if (i < local_variable_table_length - 1) {
buf.append('\n');
}
}
return buf.toString();
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
LocalVariableTable c = (LocalVariableTable) clone();
c.local_variable_table = new LocalVariable[local_variable_table_length];
for (int i = 0; i < local_variable_table_length; i++) {
c.local_variable_table[i] = local_variable_table[i].copy();
}
c.constant_pool = _constant_pool;
return c;
}
public final int getTableLength() {
return local_variable_table_length;
}
} }

View File

@ -23,232 +23,238 @@ import org.apache.bcel.generic.Type;
import org.apache.bcel.util.BCELComparator; import org.apache.bcel.util.BCELComparator;
/** /**
* This class represents the method info structure, i.e., the representation * This class represents the method info structure, i.e., the representation for
* for a method in the class. See JVM specification for details. * a method in the class. See JVM specification for details. A method has access
* A method has access flags, a name, a signature and a number of attributes. * flags, a name, a signature and a number of attributes.
* *
* @version $Id: Method.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Method.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class Method extends FieldOrMethod { public final class Method extends FieldOrMethod {
private static BCELComparator _cmp = new BCELComparator() { /**
*
*/
private static final long serialVersionUID = 1L;
private static BCELComparator _cmp = new BCELComparator() {
public boolean equals( Object o1, Object o2 ) { @Override
Method THIS = (Method) o1; public boolean equals(Object o1, Object o2) {
Method THAT = (Method) o2; Method THIS = (Method) o1;
return THIS.getName().equals(THAT.getName()) Method THAT = (Method) o2;
&& THIS.getSignature().equals(THAT.getSignature()); return THIS.getName().equals(THAT.getName())
} && THIS.getSignature().equals(THAT.getSignature());
}
@Override
public int hashCode(Object o) {
Method THIS = (Method) o;
return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
}
};
public int hashCode( Object o ) { /**
Method THIS = (Method) o; * Empty constructor, all attributes have to be defined via `setXXX'
return THIS.getSignature().hashCode() ^ THIS.getName().hashCode(); * methods. Use at your own risk.
} */
}; public Method() {
}
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public Method(Method c) {
super(c);
}
/** /**
* Empty constructor, all attributes have to be defined via `setXXX' * Construct object from file stream.
* methods. Use at your own risk. *
*/ * @param file
public Method() { * Input stream
} * @throws IOException
* @throws ClassFormatException
*/
Method(DataInputStream file, ConstantPool constant_pool)
throws IOException, ClassFormatException {
super(file, constant_pool);
}
/**
* @param access_flags
* Access rights of method
* @param name_index
* Points to field name in constant pool
* @param signature_index
* Points to encoded signature
* @param attributes
* Collection of attributes
* @param constant_pool
* Array of constants
*/
public Method(int access_flags, int name_index, int signature_index,
Attribute[] attributes, ConstantPool constant_pool) {
super(access_flags, name_index, signature_index, attributes,
constant_pool);
}
/** /**
* Initialize from another object. Note that both objects use the same * Called by objects that are traversing the nodes of the tree implicitely
* references (shallow copy). Use clone() for a physical copy. * defined by the contents of a Java class. I.e., the hierarchy of methods,
*/ * fields, attributes, etc. spawns a tree of objects.
public Method(Method c) { *
super(c); * @param v
} * Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitMethod(this);
}
/**
* @return Code attribute of method, if any
*/
public final Code getCode() {
for (int i = 0; i < attributes_count; i++) {
if (attributes[i] instanceof Code) {
return (Code) attributes[i];
}
}
return null;
}
/** /**
* Construct object from file stream. * @return ExceptionTable attribute of method, if any, i.e., list all
* @param file Input stream * exceptions the method may throw not exception handlers!
* @throws IOException */
* @throws ClassFormatException public final ExceptionTable getExceptionTable() {
*/ for (int i = 0; i < attributes_count; i++) {
Method(DataInputStream file, ConstantPool constant_pool) throws IOException, if (attributes[i] instanceof ExceptionTable) {
ClassFormatException { return (ExceptionTable) attributes[i];
super(file, constant_pool); }
} }
return null;
}
/**
* @return LocalVariableTable of code attribute if any, i.e. the call is
* forwarded to the Code atribute.
*/
public final LocalVariableTable getLocalVariableTable() {
Code code = getCode();
if (code == null) {
return null;
}
return code.getLocalVariableTable();
}
/** /**
* @param access_flags Access rights of method * @return LineNumberTable of code attribute if any, i.e. the call is
* @param name_index Points to field name in constant pool * forwarded to the Code atribute.
* @param signature_index Points to encoded signature */
* @param attributes Collection of attributes public final LineNumberTable getLineNumberTable() {
* @param constant_pool Array of constants Code code = getCode();
*/ if (code == null) {
public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes, return null;
ConstantPool constant_pool) { }
super(access_flags, name_index, signature_index, attributes, constant_pool); return code.getLineNumberTable();
} }
/**
* Return string representation close to declaration format, `public static
* void main(String[] args) throws IOException', e.g.
*
* @return String representation of the method.
*/
@Override
public final String toString() {
ConstantUtf8 c;
String name, signature, access; // Short cuts to constant pool
StringBuffer buf;
access = Utility.accessToString(access_flags);
// Get name and signature from constant pool
c = (ConstantUtf8) constant_pool.getConstant(signature_index,
Constants.CONSTANT_Utf8);
signature = c.getBytes();
c = (ConstantUtf8) constant_pool.getConstant(name_index,
Constants.CONSTANT_Utf8);
name = c.getBytes();
signature = Utility.methodSignatureToString(signature, name, access,
true, getLocalVariableTable());
buf = new StringBuffer(signature);
for (int i = 0; i < attributes_count; i++) {
Attribute a = attributes[i];
if (!((a instanceof Code) || (a instanceof ExceptionTable))) {
buf.append(" [").append(a.toString()).append("]");
}
}
ExceptionTable e = getExceptionTable();
if (e != null) {
String str = e.toString();
if (!str.equals("")) {
buf.append("\n\t\tthrows ").append(str);
}
}
return buf.toString();
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return deep copy of this method
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final Method copy(ConstantPool _constant_pool) {
* return (Method) copy_(_constant_pool);
* @param v Visitor object }
*/
public void accept( Visitor v ) {
v.visitMethod(this);
}
/**
* @return return type of method
*/
public Type getReturnType() {
return Type.getReturnType(getSignature());
}
/** /**
* @return Code attribute of method, if any * @return array of method argument types
*/ */
public final Code getCode() { public Type[] getArgumentTypes() {
for (int i = 0; i < attributes_count; i++) { return Type.getArgumentTypes(getSignature());
if (attributes[i] instanceof Code) { }
return (Code) attributes[i];
}
}
return null;
}
/**
* @return Comparison strategy object
*/
public static BCELComparator getComparator() {
return _cmp;
}
/** /**
* @return ExceptionTable attribute of method, if any, i.e., list all * @param comparator
* exceptions the method may throw not exception handlers! * Comparison strategy object
*/ */
public final ExceptionTable getExceptionTable() { public static void setComparator(BCELComparator comparator) {
for (int i = 0; i < attributes_count; i++) { _cmp = comparator;
if (attributes[i] instanceof ExceptionTable) { }
return (ExceptionTable) attributes[i];
}
}
return null;
}
/**
* Return value as defined by given BCELComparator strategy. By default two
* method objects are said to be equal when their names and signatures are
* equal.
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return _cmp.equals(this, obj);
}
/** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded /**
* to the Code atribute. * Return value as defined by given BCELComparator strategy. By default
*/ * return the hashcode of the method's name XOR signature.
public final LocalVariableTable getLocalVariableTable() { *
Code code = getCode(); * @see java.lang.Object#hashCode()
if (code == null) { */
return null; @Override
} public int hashCode() {
return code.getLocalVariableTable(); return _cmp.hashCode(this);
} }
/** @return LineNumberTable of code attribute if any, i.e. the call is forwarded
* to the Code atribute.
*/
public final LineNumberTable getLineNumberTable() {
Code code = getCode();
if (code == null) {
return null;
}
return code.getLineNumberTable();
}
/**
* Return string representation close to declaration format,
* `public static void main(String[] args) throws IOException', e.g.
*
* @return String representation of the method.
*/
public final String toString() {
ConstantUtf8 c;
String name, signature, access; // Short cuts to constant pool
StringBuffer buf;
access = Utility.accessToString(access_flags);
// Get name and signature from constant pool
c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8);
signature = c.getBytes();
c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
name = c.getBytes();
signature = Utility.methodSignatureToString(signature, name, access, true,
getLocalVariableTable());
buf = new StringBuffer(signature);
for (int i = 0; i < attributes_count; i++) {
Attribute a = attributes[i];
if (!((a instanceof Code) || (a instanceof ExceptionTable))) {
buf.append(" [").append(a.toString()).append("]");
}
}
ExceptionTable e = getExceptionTable();
if (e != null) {
String str = e.toString();
if (!str.equals("")) {
buf.append("\n\t\tthrows ").append(str);
}
}
return buf.toString();
}
/**
* @return deep copy of this method
*/
public final Method copy( ConstantPool _constant_pool ) {
return (Method) copy_(_constant_pool);
}
/**
* @return return type of method
*/
public Type getReturnType() {
return Type.getReturnType(getSignature());
}
/**
* @return array of method argument types
*/
public Type[] getArgumentTypes() {
return Type.getArgumentTypes(getSignature());
}
/**
* @return Comparison strategy object
*/
public static BCELComparator getComparator() {
return _cmp;
}
/**
* @param comparator Comparison strategy object
*/
public static void setComparator( BCELComparator comparator ) {
_cmp = comparator;
}
/**
* Return value as defined by given BCELComparator strategy.
* By default two method objects are said to be equal when
* their names and signatures are equal.
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals( Object obj ) {
return _cmp.equals(this, obj);
}
/**
* Return value as defined by given BCELComparator strategy.
* By default return the hashcode of the method's name XOR signature.
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return _cmp.hashCode(this);
}
} }

View File

@ -18,11 +18,11 @@ package org.apache.bcel.classfile;
/** /**
* Denote class to have an accept method(); * Denote class to have an accept method();
* *
* @version $Id: Node.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Node.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public interface Node { public interface Node {
public void accept( Visitor obj ); public void accept(Visitor obj);
} }

View File

@ -22,146 +22,154 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from <em>Attribute</em> and represents a reference * This class is derived from <em>Attribute</em> and represents a reference to a
* to a PMG attribute. * PMG attribute.
* *
* @version $Id: PMGClass.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: PMGClass.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute * @see Attribute
*/ */
public final class PMGClass extends Attribute { public final class PMGClass extends Attribute {
private int pmg_class_index, pmg_index; /**
*
*/
private static final long serialVersionUID = 1L;
private int pmg_class_index, pmg_index;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public PMGClass(PMGClass c) {
this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c
.getPMGClassIndex(), c.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * Construct object from file stream.
* references (shallow copy). Use clone() for a physical copy. *
*/ * @param name_index
public PMGClass(PMGClass c) { * Index in constant pool to CONSTANT_Utf8
this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c.getPMGClassIndex(), c * @param length
.getConstantPool()); * Content length in bytes
} * @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
PMGClass(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, file.readUnsignedShort(), file
.readUnsignedShort(), constant_pool);
}
/**
* @param name_index
* Index in constant pool to CONSTANT_Utf8
* @param length
* Content length in bytes
* @param pmg_index
* index in constant pool for source file name
* @param pmg_class_index
* Index in constant pool to CONSTANT_Utf8
* @param constant_pool
* Array of constants
*/
public PMGClass(int name_index, int length, int pmg_index,
int pmg_class_index, ConstantPool constant_pool) {
super(Constants.ATTR_PMG, name_index, length, constant_pool);
this.pmg_index = pmg_index;
this.pmg_class_index = pmg_class_index;
}
/** /**
* Construct object from file stream. * Called by objects that are traversing the nodes of the tree implicitely
* @param name_index Index in constant pool to CONSTANT_Utf8 * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param length Content length in bytes * fields, attributes, etc. spawns a tree of objects.
* @param file Input stream *
* @param constant_pool Array of constants * @param v
* @throws IOException * Visitor object
*/ */
PMGClass(int name_index, int length, DataInputStream file, ConstantPool constant_pool) @Override
throws IOException { public void accept(Visitor v) {
this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(), constant_pool); System.err.println("Visiting non-standard PMGClass object");
} }
/**
* Dump source file attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(pmg_index);
file.writeShort(pmg_class_index);
}
/** /**
* @param name_index Index in constant pool to CONSTANT_Utf8 * @return Index in constant pool of source file name.
* @param length Content length in bytes */
* @param pmg_index index in constant pool for source file name public final int getPMGClassIndex() {
* @param pmg_class_index Index in constant pool to CONSTANT_Utf8 return pmg_class_index;
* @param constant_pool Array of constants }
*/
public PMGClass(int name_index, int length, int pmg_index, int pmg_class_index,
ConstantPool constant_pool) {
super(Constants.ATTR_PMG, name_index, length, constant_pool);
this.pmg_index = pmg_index;
this.pmg_class_index = pmg_class_index;
}
/**
* @param pmg_class_index
*/
public final void setPMGClassIndex(int pmg_class_index) {
this.pmg_class_index = pmg_class_index;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return Index in constant pool of source file name.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final int getPMGIndex() {
* return pmg_index;
* @param v Visitor object }
*/
public void accept( Visitor v ) {
System.err.println("Visiting non-standard PMGClass object");
}
/**
* @param pmg_index
*/
public final void setPMGIndex(int pmg_index) {
this.pmg_index = pmg_index;
}
/** /**
* Dump source file attribute to file stream in binary format. * @return PMG name.
* */
* @param file Output file stream public final String getPMGName() {
* @throws IOException ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(pmg_index,
*/ Constants.CONSTANT_Utf8);
public final void dump( DataOutputStream file ) throws IOException { return c.getBytes();
super.dump(file); }
file.writeShort(pmg_index);
file.writeShort(pmg_class_index);
}
/**
* @return PMG class name.
*/
public final String getPMGClassName() {
ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(
pmg_class_index, Constants.CONSTANT_Utf8);
return c.getBytes();
}
/** /**
* @return Index in constant pool of source file name. * @return String representation
*/ */
public final int getPMGClassIndex() { @Override
return pmg_class_index; public final String toString() {
} return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")";
}
/**
/** * @return deep copy of this attribute
* @param pmg_class_index */
*/ @Override
public final void setPMGClassIndex( int pmg_class_index ) { public Attribute copy(ConstantPool _constant_pool) {
this.pmg_class_index = pmg_class_index; return (PMGClass) clone();
} }
/**
* @return Index in constant pool of source file name.
*/
public final int getPMGIndex() {
return pmg_index;
}
/**
* @param pmg_index
*/
public final void setPMGIndex( int pmg_index ) {
this.pmg_index = pmg_index;
}
/**
* @return PMG name.
*/
public final String getPMGName() {
ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(pmg_index,
Constants.CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return PMG class name.
*/
public final String getPMGClassName() {
ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(pmg_class_index,
Constants.CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return String representation
*/
public final String toString() {
return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")";
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
return (PMGClass) clone();
}
} }

View File

@ -23,251 +23,251 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from <em>Attribute</em> and represents a reference * This class is derived from <em>Attribute</em> and represents a reference to a
* to a GJ attribute. * GJ attribute.
* *
* @version $Id: Signature.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Signature.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute * @see Attribute
*/ */
public final class Signature extends Attribute { public final class Signature extends Attribute {
private int signature_index; /**
*
*/
private static final long serialVersionUID = 1L;
private int signature_index;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public Signature(Signature c) {
this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c
.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * Construct object from file stream.
* references (shallow copy). Use clone() for a physical copy. *
*/ * @param name_index
public Signature(Signature c) { * Index in constant pool to CONSTANT_Utf8
this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool()); * @param length
} * Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
Signature(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, file.readUnsignedShort(), constant_pool);
}
/**
* @param name_index
* Index in constant pool to CONSTANT_Utf8
* @param length
* Content length in bytes
* @param signature_index
* Index in constant pool to CONSTANT_Utf8
* @param constant_pool
* Array of constants
*/
public Signature(int name_index, int length, int signature_index,
ConstantPool constant_pool) {
super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool);
this.signature_index = signature_index;
}
/** /**
* Construct object from file stream. * Called by objects that are traversing the nodes of the tree implicitely
* @param name_index Index in constant pool to CONSTANT_Utf8 * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param length Content length in bytes * fields, attributes, etc. spawns a tree of objects.
* @param file Input stream *
* @param constant_pool Array of constants * @param v
* @throws IOException * Visitor object
*/ */
Signature(int name_index, int length, DataInputStream file, ConstantPool constant_pool) @Override
throws IOException { public void accept(Visitor v) {
this(name_index, length, file.readUnsignedShort(), constant_pool); // System.err.println("Visiting non-standard Signature object");
} v.visitSignature(this);
}
/**
* Dump source file attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(signature_index);
}
/** /**
* @param name_index Index in constant pool to CONSTANT_Utf8 * @return Index in constant pool of source file name.
* @param length Content length in bytes */
* @param signature_index Index in constant pool to CONSTANT_Utf8 public final int getSignatureIndex() {
* @param constant_pool Array of constants return signature_index;
*/ }
public Signature(int name_index, int length, int signature_index, ConstantPool constant_pool) {
super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool);
this.signature_index = signature_index;
}
/**
* @param signature_index
* the index info the constant pool of this signature
*/
public final void setSignatureIndex(int signature_index) {
this.signature_index = signature_index;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return GJ signature.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final String getSignature() {
* ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(
* @param v Visitor object signature_index, Constants.CONSTANT_Utf8);
*/ return c.getBytes();
public void accept( Visitor v ) { }
//System.err.println("Visiting non-standard Signature object");
v.visitSignature(this);
}
/**
* Extends ByteArrayInputStream to make 'unreading' chars possible.
*/
private static final class MyByteArrayInputStream extends
ByteArrayInputStream {
/** MyByteArrayInputStream(String data) {
* Dump source file attribute to file stream in binary format. super(data.getBytes());
* }
* @param file Output file stream
* @throws IOException
*/
public final void dump( DataOutputStream file ) throws IOException {
super.dump(file);
file.writeShort(signature_index);
}
final String getData() {
return new String(buf);
}
/** final void unread() {
* @return Index in constant pool of source file name. if (pos > 0) {
*/ pos--;
public final int getSignatureIndex() { }
return signature_index; }
} }
private static boolean identStart(int ch) {
return ch == 'T' || ch == 'L';
}
/** private static final void matchIdent(MyByteArrayInputStream in,
* @param signature_index the index info the constant pool of this signature StringBuffer buf) {
*/ int ch;
public final void setSignatureIndex( int signature_index ) { if ((ch = in.read()) == -1) {
this.signature_index = signature_index; throw new RuntimeException("Illegal signature: " + in.getData()
} + " no ident, reaching EOF");
}
// System.out.println("return from ident:" + (char)ch);
if (!identStart(ch)) {
StringBuffer buf2 = new StringBuffer();
int count = 1;
while (Character.isJavaIdentifierPart((char) ch)) {
buf2.append((char) ch);
count++;
ch = in.read();
}
if (ch == ':') { // Ok, formal parameter
in.skip("Ljava/lang/Object".length());
buf.append(buf2);
ch = in.read();
in.unread();
// System.out.println("so far:" + buf2 + ":next:" +(char)ch);
} else {
for (int i = 0; i < count; i++) {
in.unread();
}
}
return;
}
StringBuffer buf2 = new StringBuffer();
ch = in.read();
do {
buf2.append((char) ch);
ch = in.read();
// System.out.println("within ident:"+ (char)ch);
} while ((ch != -1)
&& (Character.isJavaIdentifierPart((char) ch) || (ch == '/')));
buf.append(buf2.toString().replace('/', '.'));
// System.out.println("regular return ident:"+ (char)ch + ":" + buf2);
if (ch != -1) {
in.unread();
}
}
private static final void matchGJIdent(MyByteArrayInputStream in,
StringBuffer buf) {
int ch;
matchIdent(in, buf);
ch = in.read();
if ((ch == '<') || ch == '(') { // Parameterized or method
// System.out.println("Enter <");
buf.append((char) ch);
matchGJIdent(in, buf);
while (((ch = in.read()) != '>') && (ch != ')')) { // List of
// parameters
if (ch == -1) {
throw new RuntimeException("Illegal signature: "
+ in.getData() + " reaching EOF");
}
// System.out.println("Still no >");
buf.append(", ");
in.unread();
matchGJIdent(in, buf); // Recursive call
}
// System.out.println("Exit >");
buf.append((char) ch);
} else {
in.unread();
}
ch = in.read();
if (identStart(ch)) {
in.unread();
matchGJIdent(in, buf);
} else if (ch == ')') {
in.unread();
return;
} else if (ch != ';') {
throw new RuntimeException("Illegal signature: " + in.getData()
+ " read " + (char) ch);
}
}
/** public static String translate(String s) {
* @return GJ signature. // System.out.println("Sig:" + s);
*/ StringBuffer buf = new StringBuffer();
public final String getSignature() { matchGJIdent(new MyByteArrayInputStream(s), buf);
ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(signature_index, return buf.toString();
Constants.CONSTANT_Utf8); }
return c.getBytes();
}
/** public static final boolean isFormalParameterList(String s) {
* Extends ByteArrayInputStream to make 'unreading' chars possible. return s.startsWith("<") && (s.indexOf(':') > 0);
*/ }
private static final class MyByteArrayInputStream extends ByteArrayInputStream {
MyByteArrayInputStream(String data) { public static final boolean isActualParameterList(String s) {
super(data.getBytes()); return s.startsWith("L") && s.endsWith(">;");
} }
/**
* @return String representation
*/
@Override
public final String toString() {
String s = getSignature();
return "Signature(" + s + ")";
}
final int mark() { /**
return pos; * @return deep copy of this attribute
} */
@Override
public Attribute copy(ConstantPool _constant_pool) {
final String getData() { return (Signature) clone();
return new String(buf); }
}
final void reset( int p ) {
pos = p;
}
final void unread() {
if (pos > 0) {
pos--;
}
}
}
private static boolean identStart( int ch ) {
return ch == 'T' || ch == 'L';
}
private static final void matchIdent( MyByteArrayInputStream in, StringBuffer buf ) {
int ch;
if ((ch = in.read()) == -1) {
throw new RuntimeException("Illegal signature: " + in.getData()
+ " no ident, reaching EOF");
}
//System.out.println("return from ident:" + (char)ch);
if (!identStart(ch)) {
StringBuffer buf2 = new StringBuffer();
int count = 1;
while (Character.isJavaIdentifierPart((char) ch)) {
buf2.append((char) ch);
count++;
ch = in.read();
}
if (ch == ':') { // Ok, formal parameter
in.skip("Ljava/lang/Object".length());
buf.append(buf2);
ch = in.read();
in.unread();
//System.out.println("so far:" + buf2 + ":next:" +(char)ch);
} else {
for (int i = 0; i < count; i++) {
in.unread();
}
}
return;
}
StringBuffer buf2 = new StringBuffer();
ch = in.read();
do {
buf2.append((char) ch);
ch = in.read();
//System.out.println("within ident:"+ (char)ch);
} while ((ch != -1) && (Character.isJavaIdentifierPart((char) ch) || (ch == '/')));
buf.append(buf2.toString().replace('/', '.'));
//System.out.println("regular return ident:"+ (char)ch + ":" + buf2);
if (ch != -1) {
in.unread();
}
}
private static final void matchGJIdent( MyByteArrayInputStream in, StringBuffer buf ) {
int ch;
matchIdent(in, buf);
ch = in.read();
if ((ch == '<') || ch == '(') { // Parameterized or method
//System.out.println("Enter <");
buf.append((char) ch);
matchGJIdent(in, buf);
while (((ch = in.read()) != '>') && (ch != ')')) { // List of parameters
if (ch == -1) {
throw new RuntimeException("Illegal signature: " + in.getData()
+ " reaching EOF");
}
//System.out.println("Still no >");
buf.append(", ");
in.unread();
matchGJIdent(in, buf); // Recursive call
}
//System.out.println("Exit >");
buf.append((char) ch);
} else {
in.unread();
}
ch = in.read();
if (identStart(ch)) {
in.unread();
matchGJIdent(in, buf);
} else if (ch == ')') {
in.unread();
return;
} else if (ch != ';') {
throw new RuntimeException("Illegal signature: " + in.getData() + " read " + (char) ch);
}
}
public static String translate( String s ) {
//System.out.println("Sig:" + s);
StringBuffer buf = new StringBuffer();
matchGJIdent(new MyByteArrayInputStream(s), buf);
return buf.toString();
}
public static final boolean isFormalParameterList( String s ) {
return s.startsWith("<") && (s.indexOf(':') > 0);
}
public static final boolean isActualParameterList( String s ) {
return s.startsWith("L") && s.endsWith(">;");
}
/**
* @return String representation
*/
public final String toString() {
String s = getSignature();
return "Signature(" + s + ")";
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
return (Signature) clone();
}
} }

View File

@ -22,124 +22,134 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class is derived from <em>Attribute</em> and represents a reference * This class is derived from <em>Attribute</em> and represents a reference to
* to the source file of this class. At most one SourceFile attribute * the source file of this class. At most one SourceFile attribute should appear
* should appear per classfile. The intention of this class is that it is * per classfile. The intention of this class is that it is instantiated from
* instantiated from the <em>Attribute.readAttribute()</em> method. * the <em>Attribute.readAttribute()</em> method.
* *
* @version $Id: SourceFile.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: SourceFile.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute * @see Attribute
*/ */
public final class SourceFile extends Attribute { public final class SourceFile extends Attribute {
private int sourcefile_index; /**
*
*/
private static final long serialVersionUID = 1L;
private int sourcefile_index;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public SourceFile(SourceFile c) {
this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c
.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * Construct object from file stream.
* references (shallow copy). Use clone() for a physical copy. *
*/ * @param name_index
public SourceFile(SourceFile c) { * Index in constant pool to CONSTANT_Utf8
this(c.getNameIndex(), c.getLength(), c.getSourceFileIndex(), c.getConstantPool()); * @param length
} * Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
SourceFile(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, file.readUnsignedShort(), constant_pool);
}
/**
* @param name_index
* Index in constant pool to CONSTANT_Utf8, which should
* represent the string "SourceFile".
* @param length
* Content length in bytes, the value should be 2.
* @param constant_pool
* The constant pool that this attribute is associated with.
* @param sourcefile_index
* Index in constant pool to CONSTANT_Utf8. This string will be
* interpreted as the name of the file from which this class was
* compiled. It will not be interpreted as indicating the name of
* the directory contqining the file or an absolute path; this
* information has to be supplied the consumer of this attribute
* - in many cases, the JVM.
*/
public SourceFile(int name_index, int length, int sourcefile_index,
ConstantPool constant_pool) {
super(Constants.ATTR_SOURCE_FILE, name_index, length, constant_pool);
this.sourcefile_index = sourcefile_index;
}
/** /**
* Construct object from file stream. * Called by objects that are traversing the nodes of the tree implicitely
* @param name_index Index in constant pool to CONSTANT_Utf8 * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param length Content length in bytes * fields, attributes, etc. spawns a tree of objects.
* @param file Input stream *
* @param constant_pool Array of constants * @param v
* @throws IOException * Visitor object
*/ */
SourceFile(int name_index, int length, DataInputStream file, ConstantPool constant_pool) @Override
throws IOException { public void accept(Visitor v) {
this(name_index, length, file.readUnsignedShort(), constant_pool); v.visitSourceFile(this);
} }
/**
* Dump source file attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(sourcefile_index);
}
/** /**
* @param name_index Index in constant pool to CONSTANT_Utf8, which * @return Index in constant pool of source file name.
* should represent the string "SourceFile". */
* @param length Content length in bytes, the value should be 2. public final int getSourceFileIndex() {
* @param constant_pool The constant pool that this attribute is return sourcefile_index;
* associated with. }
* @param sourcefile_index Index in constant pool to CONSTANT_Utf8. This
* string will be interpreted as the name of the file from which this
* class was compiled. It will not be interpreted as indicating the name
* of the directory contqining the file or an absolute path; this
* information has to be supplied the consumer of this attribute - in
* many cases, the JVM.
*/
public SourceFile(int name_index, int length, int sourcefile_index, ConstantPool constant_pool) {
super(Constants.ATTR_SOURCE_FILE, name_index, length, constant_pool);
this.sourcefile_index = sourcefile_index;
}
/**
* @param sourcefile_index
*/
public final void setSourceFileIndex(int sourcefile_index) {
this.sourcefile_index = sourcefile_index;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return Source file name.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. public final String getSourceFileName() {
* ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(
* @param v Visitor object sourcefile_index, Constants.CONSTANT_Utf8);
*/ return c.getBytes();
public void accept( Visitor v ) { }
v.visitSourceFile(this);
}
/**
* @return String representation
*/
@Override
public final String toString() {
return "SourceFile(" + getSourceFileName() + ")";
}
/** /**
* Dump source file attribute to file stream in binary format. * @return deep copy of this attribute
* */
* @param file Output file stream @Override
* @throws IOException public Attribute copy(ConstantPool _constant_pool) {
*/ return (SourceFile) clone();
public final void dump( DataOutputStream file ) throws IOException { }
super.dump(file);
file.writeShort(sourcefile_index);
}
/**
* @return Index in constant pool of source file name.
*/
public final int getSourceFileIndex() {
return sourcefile_index;
}
/**
* @param sourcefile_index
*/
public final void setSourceFileIndex( int sourcefile_index ) {
this.sourcefile_index = sourcefile_index;
}
/**
* @return Source file name.
*/
public final String getSourceFileName() {
ConstantUtf8 c = (ConstantUtf8) constant_pool.getConstant(sourcefile_index,
Constants.CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return String representation
*/
public final String toString() {
return "SourceFile(" + getSourceFileName() + ")";
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
return (SourceFile) clone();
}
} }

View File

@ -22,132 +22,141 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents a stack map attribute used for * This class represents a stack map attribute used for preverification of Java
* preverification of Java classes for the <a * classes for the <a href="http://java.sun.com/j2me/"> Java 2 Micro Edition</a>
* href="http://java.sun.com/j2me/"> Java 2 Micro Edition</a>
* (J2ME). This attribute is used by the <a * (J2ME). This attribute is used by the <a
* href="http://java.sun.com/products/cldc/">KVM</a> and contained * href="http://java.sun.com/products/cldc/">KVM</a> and contained within the
* within the Code attribute of a method. See CLDC specification * Code attribute of a method. See CLDC specification 5.3.1.2
* 5.3.1.2 *
*
* @version $Id: StackMap.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: StackMap.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Code * @see Code
* @see StackMapEntry * @see StackMapEntry
* @see StackMapType * @see StackMapType
*/ */
public final class StackMap extends Attribute implements Node { public final class StackMap extends Attribute implements Node {
private int map_length; /**
private StackMapEntry[] map; // Table of stack map entries *
*/
private static final long serialVersionUID = 1L;
private int map_length;
private StackMapEntry[] map; // Table of stack map entries
/*
* @param name_index Index of name
*
* @param length Content length in bytes
*
* @param map Table of stack map entries
*
* @param constant_pool Array of constants
*/
public StackMap(int name_index, int length, StackMapEntry[] map,
ConstantPool constant_pool) {
super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool);
setStackMap(map);
}
/* /**
* @param name_index Index of name * Construct object from file stream.
* @param length Content length in bytes *
* @param map Table of stack map entries * @param name_index
* @param constant_pool Array of constants * Index of name
*/ * @param length
public StackMap(int name_index, int length, StackMapEntry[] map, ConstantPool constant_pool) { * Content length in bytes
super(Constants.ATTR_STACK_MAP, name_index, length, constant_pool); * @param file
setStackMap(map); * Input stream
} * @param constant_pool
* Array of constants
* @throws IOException
*/
StackMap(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, (StackMapEntry[]) null, constant_pool);
map_length = file.readUnsignedShort();
map = new StackMapEntry[map_length];
for (int i = 0; i < map_length; i++) {
map[i] = new StackMapEntry(file, constant_pool);
}
}
/**
* Dump line number table attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
file.writeShort(map_length);
for (int i = 0; i < map_length; i++) {
map[i].dump(file);
}
}
/** /**
* Construct object from file stream. * @return Array of stack map entries
* @param name_index Index of name */
* @param length Content length in bytes public final StackMapEntry[] getStackMap() {
* @param file Input stream return map;
* @param constant_pool Array of constants }
* @throws IOException
*/
StackMap(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, (StackMapEntry[]) null, constant_pool);
map_length = file.readUnsignedShort();
map = new StackMapEntry[map_length];
for (int i = 0; i < map_length; i++) {
map[i] = new StackMapEntry(file, constant_pool);
}
}
/**
* @param map
* Array of stack map entries
*/
public final void setStackMap(StackMapEntry[] map) {
this.map = map;
map_length = (map == null) ? 0 : map.length;
}
/** /**
* Dump line number table attribute to file stream in binary format. * @return String representation.
* */
* @param file Output file stream @Override
* @throws IOException public final String toString() {
*/ StringBuffer buf = new StringBuffer("StackMap(");
public final void dump( DataOutputStream file ) throws IOException { for (int i = 0; i < map_length; i++) {
super.dump(file); buf.append(map[i].toString());
file.writeShort(map_length); if (i < map_length - 1) {
for (int i = 0; i < map_length; i++) { buf.append(", ");
map[i].dump(file); }
} }
} buf.append(')');
return buf.toString();
}
/**
* @return deep copy of this attribute
*/
@Override
public Attribute copy(ConstantPool _constant_pool) {
StackMap c = (StackMap) clone();
c.map = new StackMapEntry[map_length];
for (int i = 0; i < map_length; i++) {
c.map[i] = map[i].copy();
}
c.constant_pool = _constant_pool;
return c;
}
/** /**
* @return Array of stack map entries * Called by objects that are traversing the nodes of the tree implicitely
*/ * defined by the contents of a Java class. I.e., the hierarchy of methods,
public final StackMapEntry[] getStackMap() { * fields, attributes, etc. spawns a tree of objects.
return map; *
} * @param v
* Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitStackMap(this);
}
public final int getMapLength() {
/** return map_length;
* @param map Array of stack map entries }
*/
public final void setStackMap( StackMapEntry[] map ) {
this.map = map;
map_length = (map == null) ? 0 : map.length;
}
/**
* @return String representation.
*/
public final String toString() {
StringBuffer buf = new StringBuffer("StackMap(");
for (int i = 0; i < map_length; i++) {
buf.append(map[i].toString());
if (i < map_length - 1) {
buf.append(", ");
}
}
buf.append(')');
return buf.toString();
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
StackMap c = (StackMap) clone();
c.map = new StackMapEntry[map_length];
for (int i = 0; i < map_length; i++) {
c.map[i] = map[i].copy();
}
c.constant_pool = _constant_pool;
return c;
}
/**
* Called by objects that are traversing the nodes of the tree implicitely
* defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v Visitor object
*/
public void accept( Visitor v ) {
v.visitStackMap(this);
}
public final int getMapLength() {
return map_length;
}
} }

View File

@ -21,192 +21,181 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
/** /**
* This class represents a stack map entry recording the types of * This class represents a stack map entry recording the types of local
* local variables and the the of stack items at a given byte code offset. * variables and the the of stack items at a given byte code offset. See CLDC
* See CLDC specification 5.3.1.2 * specification 5.3.1.2
* *
* @version $Id: StackMapEntry.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: StackMapEntry.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see StackMap * @see StackMap
* @see StackMapType * @see StackMapType
*/ */
public final class StackMapEntry implements Cloneable { public final class StackMapEntry implements Cloneable {
private int byte_code_offset; private int byte_code_offset;
private int number_of_locals; private int number_of_locals;
private StackMapType[] types_of_locals; private StackMapType[] types_of_locals;
private int number_of_stack_items; private int number_of_stack_items;
private StackMapType[] types_of_stack_items; private StackMapType[] types_of_stack_items;
private ConstantPool constant_pool; private ConstantPool constant_pool;
/**
* Construct object from file stream.
*
* @param file
* Input stream
* @throws IOException
*/
StackMapEntry(DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(file.readShort(), file.readShort(), null, -1, null, constant_pool);
types_of_locals = new StackMapType[number_of_locals];
for (int i = 0; i < number_of_locals; i++) {
types_of_locals[i] = new StackMapType(file, constant_pool);
}
number_of_stack_items = file.readShort();
types_of_stack_items = new StackMapType[number_of_stack_items];
for (int i = 0; i < number_of_stack_items; i++) {
types_of_stack_items[i] = new StackMapType(file, constant_pool);
}
}
/** public StackMapEntry(int byte_code_offset, int number_of_locals,
* Construct object from file stream. StackMapType[] types_of_locals, int number_of_stack_items,
* @param file Input stream StackMapType[] types_of_stack_items, ConstantPool constant_pool) {
* @throws IOException this.byte_code_offset = byte_code_offset;
*/ this.number_of_locals = number_of_locals;
StackMapEntry(DataInputStream file, ConstantPool constant_pool) throws IOException { this.types_of_locals = types_of_locals;
this(file.readShort(), file.readShort(), null, -1, null, constant_pool); this.number_of_stack_items = number_of_stack_items;
types_of_locals = new StackMapType[number_of_locals]; this.types_of_stack_items = types_of_stack_items;
for (int i = 0; i < number_of_locals; i++) { this.constant_pool = constant_pool;
types_of_locals[i] = new StackMapType(file, constant_pool); }
}
number_of_stack_items = file.readShort();
types_of_stack_items = new StackMapType[number_of_stack_items];
for (int i = 0; i < number_of_stack_items; i++) {
types_of_stack_items[i] = new StackMapType(file, constant_pool);
}
}
/**
* Dump stack map entry
*
* @param file
* Output file stream
* @throws IOException
*/
public final void dump(DataOutputStream file) throws IOException {
file.writeShort(byte_code_offset);
file.writeShort(number_of_locals);
for (int i = 0; i < number_of_locals; i++) {
types_of_locals[i].dump(file);
}
file.writeShort(number_of_stack_items);
for (int i = 0; i < number_of_stack_items; i++) {
types_of_stack_items[i].dump(file);
}
}
public StackMapEntry(int byte_code_offset, int number_of_locals, /**
StackMapType[] types_of_locals, int number_of_stack_items, * @return String representation.
StackMapType[] types_of_stack_items, ConstantPool constant_pool) { */
this.byte_code_offset = byte_code_offset; @Override
this.number_of_locals = number_of_locals; public final String toString() {
this.types_of_locals = types_of_locals; StringBuffer buf = new StringBuffer(64);
this.number_of_stack_items = number_of_stack_items; buf.append("(offset=").append(byte_code_offset);
this.types_of_stack_items = types_of_stack_items; if (number_of_locals > 0) {
this.constant_pool = constant_pool; buf.append(", locals={");
} for (int i = 0; i < number_of_locals; i++) {
buf.append(types_of_locals[i]);
if (i < number_of_locals - 1) {
buf.append(", ");
}
}
buf.append("}");
}
if (number_of_stack_items > 0) {
buf.append(", stack items={");
for (int i = 0; i < number_of_stack_items; i++) {
buf.append(types_of_stack_items[i]);
if (i < number_of_stack_items - 1) {
buf.append(", ");
}
}
buf.append("}");
}
buf.append(")");
return buf.toString();
}
public void setByteCodeOffset(int b) {
byte_code_offset = b;
}
/** public int getByteCodeOffset() {
* Dump stack map entry return byte_code_offset;
* }
* @param file Output file stream
* @throws IOException
*/
public final void dump( DataOutputStream file ) throws IOException {
file.writeShort(byte_code_offset);
file.writeShort(number_of_locals);
for (int i = 0; i < number_of_locals; i++) {
types_of_locals[i].dump(file);
}
file.writeShort(number_of_stack_items);
for (int i = 0; i < number_of_stack_items; i++) {
types_of_stack_items[i].dump(file);
}
}
public void setNumberOfLocals(int n) {
number_of_locals = n;
}
/** public int getNumberOfLocals() {
* @return String representation. return number_of_locals;
*/ }
public final String toString() {
StringBuffer buf = new StringBuffer(64);
buf.append("(offset=").append(byte_code_offset);
if (number_of_locals > 0) {
buf.append(", locals={");
for (int i = 0; i < number_of_locals; i++) {
buf.append(types_of_locals[i]);
if (i < number_of_locals - 1) {
buf.append(", ");
}
}
buf.append("}");
}
if (number_of_stack_items > 0) {
buf.append(", stack items={");
for (int i = 0; i < number_of_stack_items; i++) {
buf.append(types_of_stack_items[i]);
if (i < number_of_stack_items - 1) {
buf.append(", ");
}
}
buf.append("}");
}
buf.append(")");
return buf.toString();
}
public void setTypesOfLocals(StackMapType[] t) {
types_of_locals = t;
}
public void setByteCodeOffset( int b ) { public StackMapType[] getTypesOfLocals() {
byte_code_offset = b; return types_of_locals;
} }
public void setNumberOfStackItems(int n) {
number_of_stack_items = n;
}
public int getByteCodeOffset() { public int getNumberOfStackItems() {
return byte_code_offset; return number_of_stack_items;
} }
public void setTypesOfStackItems(StackMapType[] t) {
types_of_stack_items = t;
}
public void setNumberOfLocals( int n ) { public StackMapType[] getTypesOfStackItems() {
number_of_locals = n; return types_of_stack_items;
} }
/**
* @return deep copy of this object
*/
public StackMapEntry copy() {
try {
return (StackMapEntry) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
public int getNumberOfLocals() { /**
return number_of_locals; * Called by objects that are traversing the nodes of the tree implicitely
} * defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v
* Visitor object
*/
public void accept(Visitor v) {
v.visitStackMapEntry(this);
}
/**
* @return Constant pool used by this object.
*/
public final ConstantPool getConstantPool() {
return constant_pool;
}
public void setTypesOfLocals( StackMapType[] t ) { /**
types_of_locals = t; * @param constant_pool
} * Constant pool to be used for this object.
*/
public final void setConstantPool(ConstantPool constant_pool) {
public StackMapType[] getTypesOfLocals() { this.constant_pool = constant_pool;
return types_of_locals; }
}
public void setNumberOfStackItems( int n ) {
number_of_stack_items = n;
}
public int getNumberOfStackItems() {
return number_of_stack_items;
}
public void setTypesOfStackItems( StackMapType[] t ) {
types_of_stack_items = t;
}
public StackMapType[] getTypesOfStackItems() {
return types_of_stack_items;
}
/**
* @return deep copy of this object
*/
public StackMapEntry copy() {
try {
return (StackMapEntry) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
/**
* Called by objects that are traversing the nodes of the tree implicitely
* defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v Visitor object
*/
public void accept( Visitor v ) {
v.visitStackMapEntry(this);
}
/**
* @return Constant pool used by this object.
*/
public final ConstantPool getConstantPool() {
return constant_pool;
}
/**
* @param constant_pool Constant pool to be used for this object.
*/
public final void setConstantPool( ConstantPool constant_pool ) {
this.constant_pool = constant_pool;
}
} }

View File

@ -22,140 +22,139 @@ import java.io.IOException;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents the type of a local variable or item on stack * This class represents the type of a local variable or item on stack used in
* used in the StackMap entries. * the StackMap entries.
* *
* @version $Id: StackMapType.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: StackMapType.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see StackMapEntry * @see StackMapEntry
* @see StackMap * @see StackMap
* @see Constants * @see Constants
*/ */
public final class StackMapType implements Cloneable { public final class StackMapType implements Cloneable {
private byte type; private byte type;
private int index = -1; // Index to CONSTANT_Class or offset private int index = -1; // Index to CONSTANT_Class or offset
private ConstantPool constant_pool; private ConstantPool constant_pool;
/**
* Construct object from file stream.
*
* @param file
* Input stream
* @throws IOException
*/
StackMapType(DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(file.readByte(), -1, constant_pool);
if (hasIndex()) {
setIndex(file.readShort());
}
setConstantPool(constant_pool);
}
/** /**
* Construct object from file stream. * @param type
* @param file Input stream * type tag as defined in the Constants interface
* @throws IOException * @param index
*/ * index to constant pool, or byte code offset
StackMapType(DataInputStream file, ConstantPool constant_pool) throws IOException { */
this(file.readByte(), -1, constant_pool); public StackMapType(byte type, int index, ConstantPool constant_pool) {
if (hasIndex()) { setType(type);
setIndex(file.readShort()); setIndex(index);
} setConstantPool(constant_pool);
setConstantPool(constant_pool); }
}
public void setType(byte t) {
if ((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) {
throw new RuntimeException("Illegal type for StackMapType: " + t);
}
type = t;
}
/** public byte getType() {
* @param type type tag as defined in the Constants interface return type;
* @param index index to constant pool, or byte code offset }
*/
public StackMapType(byte type, int index, ConstantPool constant_pool) {
setType(type);
setIndex(index);
setConstantPool(constant_pool);
}
public void setIndex(int t) {
index = t;
}
public void setType( byte t ) { /**
if ((t < Constants.ITEM_Bogus) || (t > Constants.ITEM_NewObject)) { * @return index to constant pool if type == ITEM_Object, or offset in byte
throw new RuntimeException("Illegal type for StackMapType: " + t); * code, if type == ITEM_NewObject, and -1 otherwise
} */
type = t; public int getIndex() {
} return index;
}
/**
* Dump type entries to file.
*
* @param file
* Output file stream
* @throws IOException
*/
public final void dump(DataOutputStream file) throws IOException {
file.writeByte(type);
if (hasIndex()) {
file.writeShort(getIndex());
}
}
public byte getType() { /**
return type; * @return true, if type is either ITEM_Object or ITEM_NewObject
} */
public final boolean hasIndex() {
return ((type == Constants.ITEM_Object) || (type == Constants.ITEM_NewObject));
}
private String printIndex() {
if (type == Constants.ITEM_Object) {
if (index < 0) {
return ", class=<unknown>";
}
return ", class="
+ constant_pool.constantToString(index,
Constants.CONSTANT_Class);
} else if (type == Constants.ITEM_NewObject) {
return ", offset=" + index;
} else {
return "";
}
}
public void setIndex( int t ) { /**
index = t; * @return String representation
} */
@Override
public final String toString() {
return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")";
}
/**
* @return deep copy of this object
*/
public StackMapType copy() {
try {
return (StackMapType) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
/** @return index to constant pool if type == ITEM_Object, or offset /**
* in byte code, if type == ITEM_NewObject, and -1 otherwise * @return Constant pool used by this object.
*/ */
public int getIndex() { public final ConstantPool getConstantPool() {
return index; return constant_pool;
} }
/**
/** * @param constant_pool
* Dump type entries to file. * Constant pool to be used for this object.
* */
* @param file Output file stream public final void setConstantPool(ConstantPool constant_pool) {
* @throws IOException this.constant_pool = constant_pool;
*/ }
public final void dump( DataOutputStream file ) throws IOException {
file.writeByte(type);
if (hasIndex()) {
file.writeShort(getIndex());
}
}
/** @return true, if type is either ITEM_Object or ITEM_NewObject
*/
public final boolean hasIndex() {
return ((type == Constants.ITEM_Object) || (type == Constants.ITEM_NewObject));
}
private String printIndex() {
if (type == Constants.ITEM_Object) {
if (index < 0) {
return ", class=<unknown>";
}
return ", class=" + constant_pool.constantToString(index, Constants.CONSTANT_Class);
} else if (type == Constants.ITEM_NewObject) {
return ", offset=" + index;
} else {
return "";
}
}
/**
* @return String representation
*/
public final String toString() {
return "(type=" + Constants.ITEM_NAMES[type] + printIndex() + ")";
}
/**
* @return deep copy of this object
*/
public StackMapType copy() {
try {
return (StackMapType) clone();
} catch (CloneNotSupportedException e) {
}
return null;
}
/**
* @return Constant pool used by this object.
*/
public final ConstantPool getConstantPool() {
return constant_pool;
}
/**
* @param constant_pool Constant pool to be used for this object.
*/
public final void setConstantPool( ConstantPool constant_pool ) {
this.constant_pool = constant_pool;
}
} }

View File

@ -23,128 +23,137 @@ import org.apache.bcel.Constants;
/** /**
* This class is derived from <em>Attribute</em> and declares this class as * This class is derived from <em>Attribute</em> and declares this class as
* `synthetic', i.e., it needs special handling. The JVM specification * `synthetic', i.e., it needs special handling. The JVM specification states "A
* states "A class member that does not appear in the source code must be * class member that does not appear in the source code must be marked using a
* marked using a Synthetic attribute." It may appear in the ClassFile * Synthetic attribute." It may appear in the ClassFile attribute table, a
* attribute table, a field_info table or a method_info table. This class * field_info table or a method_info table. This class is intended to be
* is intended to be instantiated from the * instantiated from the <em>Attribute.readAttribute()</em> method.
* <em>Attribute.readAttribute()</em> method. *
*
* @version $Id: Synthetic.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Synthetic.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Attribute * @see Attribute
*/ */
public final class Synthetic extends Attribute { public final class Synthetic extends Attribute {
private byte[] bytes; /**
*
*/
private static final long serialVersionUID = 1L;
private byte[] bytes;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use copy() for a physical copy.
*/
public Synthetic(Synthetic c) {
this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
}
/** /**
* Initialize from another object. Note that both objects use the same * @param name_index
* references (shallow copy). Use copy() for a physical copy. * Index in constant pool to CONSTANT_Utf8, which should
*/ * represent the string "Synthetic".
public Synthetic(Synthetic c) { * @param length
this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); * Content length in bytes - should be zero.
} * @param bytes
* Attribute contents
* @param constant_pool
* The constant pool this attribute is associated with.
*/
public Synthetic(int name_index, int length, byte[] bytes,
ConstantPool constant_pool) {
super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool);
this.bytes = bytes;
}
/**
* Construct object from file stream.
*
* @param name_index
* Index in constant pool to CONSTANT_Utf8
* @param length
* Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
Synthetic(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, (byte[]) null, constant_pool);
if (length > 0) {
bytes = new byte[length];
file.readFully(bytes);
System.err.println("Synthetic attribute with length > 0");
}
}
/** /**
* @param name_index Index in constant pool to CONSTANT_Utf8, which * Called by objects that are traversing the nodes of the tree implicitely
* should represent the string "Synthetic". * defined by the contents of a Java class. I.e., the hierarchy of methods,
* @param length Content length in bytes - should be zero. * fields, attributes, etc. spawns a tree of objects.
* @param bytes Attribute contents *
* @param constant_pool The constant pool this attribute is associated * @param v
* with. * Visitor object
*/ */
public Synthetic(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { @Override
super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool); public void accept(Visitor v) {
this.bytes = bytes; v.visitSynthetic(this);
} }
/**
* Dump source file attribute to file stream in binary format.
*
* @param file
* Output file stream
* @throws IOException
*/
@Override
public final void dump(DataOutputStream file) throws IOException {
super.dump(file);
if (length > 0) {
file.write(bytes, 0, length);
}
}
/** /**
* Construct object from file stream. * @return data bytes.
* @param name_index Index in constant pool to CONSTANT_Utf8 */
* @param length Content length in bytes public final byte[] getBytes() {
* @param file Input stream return bytes;
* @param constant_pool Array of constants }
* @throws IOException
*/
Synthetic(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, (byte[]) null, constant_pool);
if (length > 0) {
bytes = new byte[length];
file.readFully(bytes);
System.err.println("Synthetic attribute with length > 0");
}
}
/**
* @param bytes
*/
public final void setBytes(byte[] bytes) {
this.bytes = bytes;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object StringBuffer buf = new StringBuffer("Synthetic");
*/ if (length > 0) {
public void accept( Visitor v ) { buf.append(" ").append(Utility.toHexString(bytes));
v.visitSynthetic(this); }
} return buf.toString();
}
/**
/** * @return deep copy of this attribute
* Dump source file attribute to file stream in binary format. */
* @Override
* @param file Output file stream public Attribute copy(ConstantPool _constant_pool) {
* @throws IOException Synthetic c = (Synthetic) clone();
*/ if (bytes != null) {
public final void dump( DataOutputStream file ) throws IOException { c.bytes = new byte[bytes.length];
super.dump(file); System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
if (length > 0) { }
file.write(bytes, 0, length); c.constant_pool = _constant_pool;
} return c;
} }
/**
* @return data bytes.
*/
public final byte[] getBytes() {
return bytes;
}
/**
* @param bytes
*/
public final void setBytes( byte[] bytes ) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
StringBuffer buf = new StringBuffer("Synthetic");
if (length > 0) {
buf.append(" ").append(Utility.toHexString(bytes));
}
return buf.toString();
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
Synthetic c = (Synthetic) clone();
if (bytes != null) {
c.bytes = new byte[bytes.length];
System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
}
c.constant_pool = _constant_pool;
return c;
}
} }

View File

@ -22,167 +22,178 @@ import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* This class represents a reference to an unknown (i.e., * This class represents a reference to an unknown (i.e., application-specific)
* application-specific) attribute of a class. It is instantiated from the * attribute of a class. It is instantiated from the
* <em>Attribute.readAttribute()</em> method. Applications that need to * <em>Attribute.readAttribute()</em> method. Applications that need to read in
* read in application-specific attributes should create an <a * application-specific attributes should create an <a
* href="./AttributeReader.html">AttributeReader</a> implementation and * href="./AttributeReader.html">AttributeReader</a> implementation and attach
* attach it via <a * it via <a href="./Attribute.html#addAttributeReader(java.lang.String,
* href="./Attribute.html#addAttributeReader(java.lang.String,
* org.apache.bcel.classfile.AttributeReader)">Attribute.addAttributeReader</a>. * org.apache.bcel.classfile.AttributeReader)">Attribute.addAttributeReader</a>.
*
* *
* @version $Id: Unknown.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Unknown.java 386056 2006-03-15 11:31:56Z tcurdt $
* @see org.apache.bcel.classfile.Attribute * @see org.apache.bcel.classfile.Attribute
* @see org.apache.bcel.classfile.AttributeReader * @see org.apache.bcel.classfile.AttributeReader
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class Unknown extends Attribute { public final class Unknown extends Attribute {
private byte[] bytes; /**
private String name; *
private static Map unknown_attributes = new HashMap(); */
private static final long serialVersionUID = 1L;
private byte[] bytes;
private String name;
private static Map<String, Unknown> unknown_attributes = new HashMap<String, Unknown>();
/**
* @return array of unknown attributes, but just one for each kind.
*/
static Unknown[] getUnknownAttributes() {
Unknown[] unknowns = new Unknown[unknown_attributes.size()];
Iterator<Unknown> entries = unknown_attributes.values().iterator();
for (int i = 0; entries.hasNext(); i++) {
unknowns[i] = entries.next();
}
unknown_attributes.clear();
return unknowns;
}
/** @return array of unknown attributes, but just one for each kind. /**
*/ * Initialize from another object. Note that both objects use the same
static Unknown[] getUnknownAttributes() { * references (shallow copy). Use clone() for a physical copy.
Unknown[] unknowns = new Unknown[unknown_attributes.size()]; */
Iterator entries = unknown_attributes.values().iterator(); public Unknown(Unknown c) {
for (int i = 0; entries.hasNext(); i++) { this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
unknowns[i] = (Unknown) entries.next(); }
}
unknown_attributes.clear();
return unknowns;
}
/**
* Create a non-standard attribute.
*
* @param name_index
* Index in constant pool
* @param length
* Content length in bytes
* @param bytes
* Attribute contents
* @param constant_pool
* Array of constants
*/
public Unknown(int name_index, int length, byte[] bytes,
ConstantPool constant_pool) {
super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool);
this.bytes = bytes;
name = ((ConstantUtf8) constant_pool.getConstant(name_index,
Constants.CONSTANT_Utf8)).getBytes();
unknown_attributes.put(name, this);
}
/** /**
* Initialize from another object. Note that both objects use the same * Construct object from file stream.
* references (shallow copy). Use clone() for a physical copy. *
*/ * @param name_index
public Unknown(Unknown c) { * Index in constant pool
this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool()); * @param length
} * Content length in bytes
* @param file
* Input stream
* @param constant_pool
* Array of constants
* @throws IOException
*/
Unknown(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException {
this(name_index, length, (byte[]) null, constant_pool);
if (length > 0) {
bytes = new byte[length];
file.readFully(bytes);
}
}
/**
* Called by objects that are traversing the nodes of the tree implicitely
* defined by the contents of a Java class. I.e., the hierarchy of methods,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v
* Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitUnknown(this);
}
/** /**
* Create a non-standard attribute. * Dump unknown bytes to file stream.
* *
* @param name_index Index in constant pool * @param file
* @param length Content length in bytes * Output file stream
* @param bytes Attribute contents * @throws IOException
* @param constant_pool Array of constants */
*/ @Override
public Unknown(int name_index, int length, byte[] bytes, ConstantPool constant_pool) { public final void dump(DataOutputStream file) throws IOException {
super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool); super.dump(file);
this.bytes = bytes; if (length > 0) {
name = ((ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8)) file.write(bytes, 0, length);
.getBytes(); }
unknown_attributes.put(name, this); }
}
/**
* @return data bytes.
*/
public final byte[] getBytes() {
return bytes;
}
/** /**
* Construct object from file stream. * @return name of attribute.
* @param name_index Index in constant pool */
* @param length Content length in bytes public final String getName() {
* @param file Input stream return name;
* @param constant_pool Array of constants }
* @throws IOException
*/
Unknown(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
throws IOException {
this(name_index, length, (byte[]) null, constant_pool);
if (length > 0) {
bytes = new byte[length];
file.readFully(bytes);
}
}
/**
* @param bytes
* the bytes to set
*/
public final void setBytes(byte[] bytes) {
this.bytes = bytes;
}
/** /**
* Called by objects that are traversing the nodes of the tree implicitely * @return String representation.
* defined by the contents of a Java class. I.e., the hierarchy of methods, */
* fields, attributes, etc. spawns a tree of objects. @Override
* public final String toString() {
* @param v Visitor object if (length == 0 || bytes == null) {
*/ return "(Unknown attribute " + name + ")";
public void accept( Visitor v ) { }
v.visitUnknown(this); String hex;
} if (length > 10) {
byte[] tmp = new byte[10];
System.arraycopy(bytes, 0, tmp, 0, 10);
hex = Utility.toHexString(tmp) + "... (truncated)";
} else {
hex = Utility.toHexString(bytes);
}
return "(Unknown attribute " + name + ": " + hex + ")";
}
/**
/** * @return deep copy of this attribute
* Dump unknown bytes to file stream. */
* @Override
* @param file Output file stream public Attribute copy(ConstantPool _constant_pool) {
* @throws IOException Unknown c = (Unknown) clone();
*/ if (bytes != null) {
public final void dump( DataOutputStream file ) throws IOException { c.bytes = new byte[bytes.length];
super.dump(file); System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
if (length > 0) { }
file.write(bytes, 0, length); c.constant_pool = _constant_pool;
} return c;
} }
/**
* @return data bytes.
*/
public final byte[] getBytes() {
return bytes;
}
/**
* @return name of attribute.
*/
public final String getName() {
return name;
}
/**
* @param bytes the bytes to set
*/
public final void setBytes( byte[] bytes ) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
if (length == 0 || bytes == null) {
return "(Unknown attribute " + name + ")";
}
String hex;
if (length > 10) {
byte[] tmp = new byte[10];
System.arraycopy(bytes, 0, tmp, 0, 10);
hex = Utility.toHexString(tmp) + "... (truncated)";
} else {
hex = Utility.toHexString(bytes);
}
return "(Unknown attribute " + name + ": " + hex + ")";
}
/**
* @return deep copy of this attribute
*/
public Attribute copy( ConstantPool _constant_pool ) {
Unknown c = (Unknown) clone();
if (bytes != null) {
c.bytes = new byte[bytes.length];
System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
}
c.constant_pool = _constant_pool;
return c;
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -17,111 +17,80 @@
package org.apache.bcel.classfile; package org.apache.bcel.classfile;
/** /**
* Interface to make use of the Visitor pattern programming style. * Interface to make use of the Visitor pattern programming style. I.e. a class
* I.e. a class that implements this interface can traverse the contents of * that implements this interface can traverse the contents of a Java class just
* a Java class just by calling the `accept' method which all classes have. * by calling the `accept' method which all classes have.
* *
* @version $Id: Visitor.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: Visitor.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public interface Visitor { public interface Visitor {
//public void visitAnnotation(Annotations obj); // public void visitAnnotation(Annotations obj);
//public void visitParameterAnnotation(ParameterAnnotations obj); // public void visitParameterAnnotation(ParameterAnnotations obj);
//public void visitAnnotationEntry(AnnotationEntry obj); // public void visitAnnotationEntry(AnnotationEntry obj);
//public void visitAnnotationDefault(AnnotationDefault obj); // public void visitAnnotationDefault(AnnotationDefault obj);
public void visitCode( Code obj ); public void visitCode(Code obj);
public void visitCodeException(CodeException obj);
public void visitCodeException( CodeException obj ); public void visitConstantClass(ConstantClass obj);
public void visitConstantDouble(ConstantDouble obj);
public void visitConstantClass( ConstantClass obj ); public void visitConstantFieldref(ConstantFieldref obj);
public void visitConstantFloat(ConstantFloat obj);
public void visitConstantDouble( ConstantDouble obj ); public void visitConstantInteger(ConstantInteger obj);
public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj);
public void visitConstantFieldref( ConstantFieldref obj ); public void visitConstantLong(ConstantLong obj);
public void visitConstantMethodref(ConstantMethodref obj);
public void visitConstantFloat( ConstantFloat obj ); public void visitConstantNameAndType(ConstantNameAndType obj);
public void visitConstantPool(ConstantPool obj);
public void visitConstantInteger( ConstantInteger obj ); public void visitConstantString(ConstantString obj);
public void visitConstantUtf8(ConstantUtf8 obj);
public void visitConstantInterfaceMethodref( ConstantInterfaceMethodref obj ); public void visitConstantValue(ConstantValue obj);
public void visitDeprecated(Deprecated obj);
public void visitConstantLong( ConstantLong obj ); public void visitExceptionTable(ExceptionTable obj);
public void visitField(Field obj);
public void visitConstantMethodref( ConstantMethodref obj ); public void visitInnerClass(InnerClass obj);
public void visitInnerClasses(InnerClasses obj);
public void visitConstantNameAndType( ConstantNameAndType obj ); public void visitJavaClass(JavaClass obj);
public void visitLineNumber(LineNumber obj);
public void visitConstantPool( ConstantPool obj ); public void visitLineNumberTable(LineNumberTable obj);
public void visitLocalVariable(LocalVariable obj);
public void visitConstantString( ConstantString obj ); public void visitLocalVariableTable(LocalVariableTable obj);
public void visitMethod(Method obj);
public void visitConstantUtf8( ConstantUtf8 obj ); public void visitSignature(Signature obj);
public void visitSourceFile(SourceFile obj);
public void visitConstantValue( ConstantValue obj ); public void visitSynthetic(Synthetic obj);
public void visitUnknown(Unknown obj);
public void visitDeprecated( Deprecated obj ); public void visitStackMap(StackMap obj);
public void visitStackMapEntry(StackMapEntry obj);
public void visitExceptionTable( ExceptionTable obj );
public void visitField( Field obj );
public void visitInnerClass( InnerClass obj );
public void visitInnerClasses( InnerClasses obj );
public void visitJavaClass( JavaClass obj );
public void visitLineNumber( LineNumber obj );
public void visitLineNumberTable( LineNumberTable obj );
public void visitLocalVariable( LocalVariable obj );
public void visitLocalVariableTable( LocalVariableTable obj );
public void visitMethod( Method obj );
public void visitSignature( Signature obj );
public void visitSourceFile( SourceFile obj );
public void visitSynthetic( Synthetic obj );
public void visitUnknown( Unknown obj );
public void visitStackMap( StackMap obj );
public void visitStackMapEntry( StackMapEntry obj );
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* AALOAD - Load reference from array * AALOAD - Load reference from array
* <PRE>Stack: ..., arrayref, index -&gt; value</PRE> *
* * <PRE>
* Stack: ..., arrayref, index -&gt; value
* </PRE>
*
* @version $Id: AALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: AALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class AALOAD extends ArrayInstruction implements StackProducer { public class AALOAD extends ArrayInstruction implements StackProducer {
/** Load reference from array /**
*/ *
public AALOAD() { */
super(org.apache.bcel.Constants.AALOAD); private static final long serialVersionUID = 1L;
}
/**
* Load reference from array
*/
public AALOAD() {
super(org.apache.bcel.Constants.AALOAD);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitStackProducer(this); @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitTypedInstruction(this); v.visitStackProducer(this);
v.visitArrayInstruction(this); v.visitExceptionThrower(this);
v.visitAALOAD(this); v.visitTypedInstruction(this);
} v.visitArrayInstruction(this);
v.visitAALOAD(this);
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* AASTORE - Store into reference array * AASTORE - Store into reference array
* <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE> *
* * <PRE>
* Stack: ..., arrayref, index, value -&gt; ...
* </PRE>
*
* @version $Id: AASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: AASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class AASTORE extends ArrayInstruction implements StackConsumer { public class AASTORE extends ArrayInstruction implements StackConsumer {
/** Store into reference array /**
*/ *
public AASTORE() { */
super(org.apache.bcel.Constants.AASTORE); private static final long serialVersionUID = 1L;
}
/**
* Store into reference array
*/
public AASTORE() {
super(org.apache.bcel.Constants.AASTORE);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitStackConsumer(this); @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitTypedInstruction(this); v.visitStackConsumer(this);
v.visitArrayInstruction(this); v.visitExceptionThrower(this);
v.visitAASTORE(this); v.visitTypedInstruction(this);
} v.visitArrayInstruction(this);
v.visitAASTORE(this);
}
} }

View File

@ -16,42 +16,53 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* ACONST_NULL - Push null reference * ACONST_NULL - Push null reference
* <PRE>Stack: ... -&gt; ..., null</PRE> *
* * <PRE>
* Stack: ... -&gt; ..., null
* </PRE>
*
* @version $Id: ACONST_NULL.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ACONST_NULL.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ACONST_NULL extends Instruction implements PushInstruction, TypedInstruction { public class ACONST_NULL extends Instruction implements PushInstruction,
TypedInstruction {
/** /**
* Push null reference *
*/ */
public ACONST_NULL() { private static final long serialVersionUID = 1L;
super(org.apache.bcel.Constants.ACONST_NULL, (short) 1);
}
/**
* Push null reference
*/
public ACONST_NULL() {
super(org.apache.bcel.Constants.ACONST_NULL, (short) 1);
}
/** @return Type.NULL /**
*/ * @return Type.NULL
public Type getType( ConstantPoolGen cp ) { */
return Type.NULL; @Override
} public Type getType(ConstantPoolGen cp) {
return Type.NULL;
}
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitPushInstruction(this); v.visitStackProducer(this);
v.visitTypedInstruction(this); v.visitPushInstruction(this);
v.visitACONST_NULL(this); v.visitTypedInstruction(this);
} v.visitACONST_NULL(this);
}
} }

View File

@ -16,42 +16,55 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* ALOAD - Load reference from local variable * ALOAD - Load reference from local variable
* <PRE>Stack: ... -&gt; ..., objectref</PRE> *
* * <PRE>
* Stack: ... -&gt; ..., objectref
* </PRE>
*
* @version $Id: ALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ALOAD extends LoadInstruction { public class ALOAD extends LoadInstruction {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
ALOAD() {
super(org.apache.bcel.Constants.ALOAD, org.apache.bcel.Constants.ALOAD_0);
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
ALOAD() {
super(org.apache.bcel.Constants.ALOAD,
org.apache.bcel.Constants.ALOAD_0);
}
/** Load reference from local variable /**
* @param n index of local variable * Load reference from local variable
*/ *
public ALOAD(int n) { * @param n
super(org.apache.bcel.Constants.ALOAD, org.apache.bcel.Constants.ALOAD_0, n); * index of local variable
} */
public ALOAD(int n) {
super(org.apache.bcel.Constants.ALOAD,
org.apache.bcel.Constants.ALOAD_0, n);
}
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
super.accept(v); public void accept(Visitor v) {
v.visitALOAD(this); super.accept(v);
} v.visitALOAD(this);
}
} }

View File

@ -18,62 +18,72 @@ package org.apache.bcel.generic;
import org.apache.bcel.ExceptionConstants; import org.apache.bcel.ExceptionConstants;
/** /**
* ANEWARRAY - Create new array of references * ANEWARRAY - Create new array of references
* <PRE>Stack: ..., count -&gt; ..., arrayref</PRE> *
* * <PRE>
* Stack: ..., count -&gt; ..., arrayref
* </PRE>
*
* @version $Id: ANEWARRAY.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ANEWARRAY.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ANEWARRAY extends CPInstruction implements LoadClass, AllocationInstruction, public class ANEWARRAY extends CPInstruction implements LoadClass,
ExceptionThrower, StackConsumer, StackProducer { AllocationInstruction, ExceptionThrower, StackConsumer, StackProducer {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
ANEWARRAY() {
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
ANEWARRAY() {
}
public ANEWARRAY(int index) { public ANEWARRAY(int index) {
super(org.apache.bcel.Constants.ANEWARRAY, index); super(org.apache.bcel.Constants.ANEWARRAY, index);
} }
@Override
public Class<?>[] getExceptions() {
Class<?>[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
System.arraycopy(
ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs,
0,
ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION;
return cs;
}
public Class[] getExceptions() { /**
Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; * Call corresponding visitor method(s). The order is: Call visitor methods
System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0, * of implemented interfaces first, then call methods according to the class
ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); * hierarchy in descending order, i.e., the most specific visitXXX() call
cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.NEGATIVE_ARRAY_SIZE_EXCEPTION; * comes last.
return cs; *
} * @param v
* Visitor object
*/
@Override
public void accept(Visitor v) {
v.visitLoadClass(this);
v.visitAllocationInstruction(this);
v.visitExceptionThrower(this);
v.visitStackProducer(this);
v.visitTypedInstruction(this);
v.visitCPInstruction(this);
v.visitANEWARRAY(this);
}
@Override
/** public ObjectType getLoadClassType(ConstantPoolGen cpg) {
* Call corresponding visitor method(s). The order is: Type t = getType(cpg);
* Call visitor methods of implemented interfaces first, then if (t instanceof ArrayType) {
* call methods according to the class hierarchy in descending order, t = ((ArrayType) t).getBasicType();
* i.e., the most specific visitXXX() call comes last. }
* return (t instanceof ObjectType) ? (ObjectType) t : null;
* @param v Visitor object }
*/
public void accept( Visitor v ) {
v.visitLoadClass(this);
v.visitAllocationInstruction(this);
v.visitExceptionThrower(this);
v.visitStackProducer(this);
v.visitTypedInstruction(this);
v.visitCPInstruction(this);
v.visitANEWARRAY(this);
}
public ObjectType getLoadClassType( ConstantPoolGen cpg ) {
Type t = getType(cpg);
if (t instanceof ArrayType) {
t = ((ArrayType) t).getBasicType();
}
return (t instanceof ObjectType) ? (ObjectType) t : null;
}
} }

View File

@ -16,36 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* ARETURN - Return reference from method * ARETURN - Return reference from method
* <PRE>Stack: ..., objectref -&gt; &lt;empty&gt;</PRE> *
* * <PRE>
* Stack: ..., objectref -&gt; &lt;empty&gt;
* </PRE>
*
* @version $Id: ARETURN.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ARETURN.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ARETURN extends ReturnInstruction { public class ARETURN extends ReturnInstruction {
/** /**
* Return reference from method *
*/ */
public ARETURN() { private static final long serialVersionUID = 1L;
super(org.apache.bcel.Constants.ARETURN);
}
/**
* Return reference from method
*/
public ARETURN() {
super(org.apache.bcel.Constants.ARETURN);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitExceptionThrower(this); @Override
v.visitTypedInstruction(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitExceptionThrower(this);
v.visitReturnInstruction(this); v.visitTypedInstruction(this);
v.visitARETURN(this); v.visitStackConsumer(this);
} v.visitReturnInstruction(this);
v.visitARETURN(this);
}
} }

View File

@ -16,42 +16,52 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* ARRAYLENGTH - Get length of array * ARRAYLENGTH - Get length of array
* <PRE>Stack: ..., arrayref -&gt; ..., length</PRE> *
* * <PRE>
* Stack: ..., arrayref -&gt; ..., length
* </PRE>
*
* @version $Id: ARRAYLENGTH.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ARRAYLENGTH.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ARRAYLENGTH extends Instruction implements ExceptionThrower, StackProducer { public class ARRAYLENGTH extends Instruction implements ExceptionThrower,
StackProducer {
/** Get length of array /**
*/ *
public ARRAYLENGTH() { */
super(org.apache.bcel.Constants.ARRAYLENGTH, (short) 1); private static final long serialVersionUID = 1L;
}
/**
* Get length of array
*/
public ARRAYLENGTH() {
super(org.apache.bcel.Constants.ARRAYLENGTH, (short) 1);
}
/** @return exceptions this instruction may cause /**
*/ * @return exceptions this instruction may cause
public Class[] getExceptions() { */
return new Class[] { @Override
org.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION public Class<?>[] getExceptions() {
}; return new Class[] { org.apache.bcel.ExceptionConstants.NULL_POINTER_EXCEPTION };
} }
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitStackProducer(this); v.visitExceptionThrower(this);
v.visitARRAYLENGTH(this); v.visitStackProducer(this);
} v.visitARRAYLENGTH(this);
}
} }

View File

@ -16,42 +16,55 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* ASTORE - Store reference into local variable * ASTORE - Store reference into local variable
* <PRE>Stack ..., objectref -&gt; ... </PRE> *
* * <PRE>
* Stack ..., objectref -&gt; ...
* </PRE>
*
* @version $Id: ASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ASTORE extends StoreInstruction { public class ASTORE extends StoreInstruction {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
ASTORE() {
super(org.apache.bcel.Constants.ASTORE, org.apache.bcel.Constants.ASTORE_0);
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
ASTORE() {
super(org.apache.bcel.Constants.ASTORE,
org.apache.bcel.Constants.ASTORE_0);
}
/** Store reference into local variable /**
* @param n index of local variable * Store reference into local variable
*/ *
public ASTORE(int n) { * @param n
super(org.apache.bcel.Constants.ASTORE, org.apache.bcel.Constants.ASTORE_0, n); * index of local variable
} */
public ASTORE(int n) {
super(org.apache.bcel.Constants.ASTORE,
org.apache.bcel.Constants.ASTORE_0, n);
}
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
super.accept(v); public void accept(Visitor v) {
v.visitASTORE(this); super.accept(v);
} v.visitASTORE(this);
}
} }

View File

@ -16,43 +16,52 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* ATHROW - Throw exception * ATHROW - Throw exception
* <PRE>Stack: ..., objectref -&gt; objectref</PRE> *
* * <PRE>
* Stack: ..., objectref -&gt; objectref
* </PRE>
*
* @version $Id: ATHROW.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ATHROW.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ATHROW extends Instruction implements UnconditionalBranch, ExceptionThrower { public class ATHROW extends Instruction implements UnconditionalBranch,
ExceptionThrower {
/** /**
* Throw exception *
*/ */
public ATHROW() { private static final long serialVersionUID = 1L;
super(org.apache.bcel.Constants.ATHROW, (short) 1);
}
/**
* Throw exception
*/
public ATHROW() {
super(org.apache.bcel.Constants.ATHROW, (short) 1);
}
/** @return exceptions this instruction may cause /**
*/ * @return exceptions this instruction may cause
public Class[] getExceptions() { */
return new Class[] { @Override
org.apache.bcel.ExceptionConstants.THROWABLE public Class<?>[] getExceptions() {
}; return new Class[] { org.apache.bcel.ExceptionConstants.THROWABLE };
} }
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
v.visitUnconditionalBranch(this); public void accept(Visitor v) {
v.visitExceptionThrower(this); v.visitUnconditionalBranch(this);
v.visitATHROW(this); v.visitExceptionThrower(this);
} v.visitATHROW(this);
}
} }

View File

@ -18,9 +18,9 @@ package org.apache.bcel.generic;
/** /**
* Denote family of instructions that allocates space in the heap. * Denote family of instructions that allocates space in the heap.
* *
* @version $Id: AllocationInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: AllocationInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public interface AllocationInstruction { public interface AllocationInstruction {
} }

View File

@ -20,75 +20,81 @@ import org.apache.bcel.Constants;
/** /**
* Super class for the family of arithmetic instructions. * Super class for the family of arithmetic instructions.
* *
* @version $Id: ArithmeticInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ArithmeticInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class ArithmeticInstruction extends Instruction implements TypedInstruction, public abstract class ArithmeticInstruction extends Instruction implements
StackProducer, StackConsumer { TypedInstruction, StackProducer, StackConsumer {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
ArithmeticInstruction() {
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
ArithmeticInstruction() {
}
/** /**
* @param opcode of instruction * @param opcode
*/ * of instruction
protected ArithmeticInstruction(short opcode) { */
super(opcode, (short) 1); protected ArithmeticInstruction(short opcode) {
} super(opcode, (short) 1);
}
/**
/** @return type associated with the instruction * @return type associated with the instruction
*/ */
public Type getType( ConstantPoolGen cp ) { @Override
switch (opcode) { public Type getType(ConstantPoolGen cp) {
case Constants.DADD: switch (opcode) {
case Constants.DDIV: case Constants.DADD:
case Constants.DMUL: case Constants.DDIV:
case Constants.DNEG: case Constants.DMUL:
case Constants.DREM: case Constants.DNEG:
case Constants.DSUB: case Constants.DREM:
return Type.DOUBLE; case Constants.DSUB:
case Constants.FADD: return Type.DOUBLE;
case Constants.FDIV: case Constants.FADD:
case Constants.FMUL: case Constants.FDIV:
case Constants.FNEG: case Constants.FMUL:
case Constants.FREM: case Constants.FNEG:
case Constants.FSUB: case Constants.FREM:
return Type.FLOAT; case Constants.FSUB:
case Constants.IADD: return Type.FLOAT;
case Constants.IAND: case Constants.IADD:
case Constants.IDIV: case Constants.IAND:
case Constants.IMUL: case Constants.IDIV:
case Constants.INEG: case Constants.IMUL:
case Constants.IOR: case Constants.INEG:
case Constants.IREM: case Constants.IOR:
case Constants.ISHL: case Constants.IREM:
case Constants.ISHR: case Constants.ISHL:
case Constants.ISUB: case Constants.ISHR:
case Constants.IUSHR: case Constants.ISUB:
case Constants.IXOR: case Constants.IUSHR:
return Type.INT; case Constants.IXOR:
case Constants.LADD: return Type.INT;
case Constants.LAND: case Constants.LADD:
case Constants.LDIV: case Constants.LAND:
case Constants.LMUL: case Constants.LDIV:
case Constants.LNEG: case Constants.LMUL:
case Constants.LOR: case Constants.LNEG:
case Constants.LREM: case Constants.LOR:
case Constants.LSHL: case Constants.LREM:
case Constants.LSHR: case Constants.LSHL:
case Constants.LSUB: case Constants.LSHR:
case Constants.LUSHR: case Constants.LSUB:
case Constants.LXOR: case Constants.LUSHR:
return Type.LONG; case Constants.LXOR:
default: // Never reached return Type.LONG;
throw new ClassGenException("Unknown type " + opcode); default: // Never reached
} throw new ClassGenException("Unknown type " + opcode);
} }
}
} }

View File

@ -18,64 +18,70 @@ package org.apache.bcel.generic;
/** /**
* Super class for instructions dealing with array access such as IALOAD. * Super class for instructions dealing with array access such as IALOAD.
* *
* @version $Id: ArrayInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ArrayInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class ArrayInstruction extends Instruction implements ExceptionThrower, public abstract class ArrayInstruction extends Instruction implements
TypedInstruction { ExceptionThrower, TypedInstruction {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
ArrayInstruction() {
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
ArrayInstruction() {
}
/** /**
* @param opcode of instruction * @param opcode
*/ * of instruction
protected ArrayInstruction(short opcode) { */
super(opcode, (short) 1); protected ArrayInstruction(short opcode) {
} super(opcode, (short) 1);
}
@Override
public Class<?>[] getExceptions() {
return org.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION;
}
public Class[] getExceptions() { /**
return org.apache.bcel.ExceptionConstants.EXCS_ARRAY_EXCEPTION; * @return type associated with the instruction
} */
@Override
public Type getType(ConstantPoolGen cp) {
/** @return type associated with the instruction switch (opcode) {
*/ case org.apache.bcel.Constants.IALOAD:
public Type getType( ConstantPoolGen cp ) { case org.apache.bcel.Constants.IASTORE:
switch (opcode) { return Type.INT;
case org.apache.bcel.Constants.IALOAD: case org.apache.bcel.Constants.CALOAD:
case org.apache.bcel.Constants.IASTORE: case org.apache.bcel.Constants.CASTORE:
return Type.INT; return Type.CHAR;
case org.apache.bcel.Constants.CALOAD: case org.apache.bcel.Constants.BALOAD:
case org.apache.bcel.Constants.CASTORE: case org.apache.bcel.Constants.BASTORE:
return Type.CHAR; return Type.BYTE;
case org.apache.bcel.Constants.BALOAD: case org.apache.bcel.Constants.SALOAD:
case org.apache.bcel.Constants.BASTORE: case org.apache.bcel.Constants.SASTORE:
return Type.BYTE; return Type.SHORT;
case org.apache.bcel.Constants.SALOAD: case org.apache.bcel.Constants.LALOAD:
case org.apache.bcel.Constants.SASTORE: case org.apache.bcel.Constants.LASTORE:
return Type.SHORT; return Type.LONG;
case org.apache.bcel.Constants.LALOAD: case org.apache.bcel.Constants.DALOAD:
case org.apache.bcel.Constants.LASTORE: case org.apache.bcel.Constants.DASTORE:
return Type.LONG; return Type.DOUBLE;
case org.apache.bcel.Constants.DALOAD: case org.apache.bcel.Constants.FALOAD:
case org.apache.bcel.Constants.DASTORE: case org.apache.bcel.Constants.FASTORE:
return Type.DOUBLE; return Type.FLOAT;
case org.apache.bcel.Constants.FALOAD: case org.apache.bcel.Constants.AALOAD:
case org.apache.bcel.Constants.FASTORE: case org.apache.bcel.Constants.AASTORE:
return Type.FLOAT; return Type.OBJECT;
case org.apache.bcel.Constants.AALOAD: default:
case org.apache.bcel.Constants.AASTORE: throw new ClassGenException("Oops: unknown case in switch" + opcode);
return Type.OBJECT; }
default: }
throw new ClassGenException("Oops: unknown case in switch" + opcode);
}
}
} }

View File

@ -18,110 +18,117 @@ package org.apache.bcel.generic;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* Denotes array type, such as int[][] * Denotes array type, such as int[][]
* *
* @version $Id: ArrayType.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ArrayType.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class ArrayType extends ReferenceType { public final class ArrayType extends ReferenceType {
private int dimensions; /**
private Type basic_type; *
*/
private static final long serialVersionUID = 1L;
private int dimensions;
private Type basic_type;
/**
* Convenience constructor for array type, e.g. int[]
*
* @param type
* array type, e.g. T_INT
*/
public ArrayType(byte type, int dimensions) {
this(BasicType.getType(type), dimensions);
}
/** /**
* Convenience constructor for array type, e.g. int[] * Convenience constructor for reference array type, e.g. Object[]
* *
* @param type array type, e.g. T_INT * @param class_name
*/ * complete name of class (java.lang.String, e.g.)
public ArrayType(byte type, int dimensions) { */
this(BasicType.getType(type), dimensions); public ArrayType(String class_name, int dimensions) {
} this(new ObjectType(class_name), dimensions);
}
/**
* Constructor for array of given type
*
* @param type
* type of array (may be an array itself)
*/
public ArrayType(Type type, int dimensions) {
super(Constants.T_ARRAY, "<dummy>");
if ((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) {
throw new ClassGenException("Invalid number of dimensions: "
+ dimensions);
}
switch (type.getType()) {
case Constants.T_ARRAY:
ArrayType array = (ArrayType) type;
this.dimensions = dimensions + array.dimensions;
basic_type = array.basic_type;
break;
case Constants.T_VOID:
throw new ClassGenException("Invalid type: void[]");
default: // Basic type or reference
this.dimensions = dimensions;
basic_type = type;
break;
}
StringBuffer buf = new StringBuffer();
for (int i = 0; i < this.dimensions; i++) {
buf.append('[');
}
buf.append(basic_type.getSignature());
signature = buf.toString();
}
/** /**
* Convenience constructor for reference array type, e.g. Object[] * @return basic type of array, i.e., for int[][][] the basic type is int
* */
* @param class_name complete name of class (java.lang.String, e.g.) public Type getBasicType() {
*/ return basic_type;
public ArrayType(String class_name, int dimensions) { }
this(new ObjectType(class_name), dimensions);
}
/**
* @return element type of array, i.e., for int[][][] the element type is
* int[][]
*/
public Type getElementType() {
if (dimensions == 1) {
return basic_type;
}
return new ArrayType(basic_type, dimensions - 1);
}
/** /**
* Constructor for array of given type * @return number of dimensions of array
* */
* @param type type of array (may be an array itself) public int getDimensions() {
*/ return dimensions;
public ArrayType(Type type, int dimensions) { }
super(Constants.T_ARRAY, "<dummy>");
if ((dimensions < 1) || (dimensions > Constants.MAX_BYTE)) {
throw new ClassGenException("Invalid number of dimensions: " + dimensions);
}
switch (type.getType()) {
case Constants.T_ARRAY:
ArrayType array = (ArrayType) type;
this.dimensions = dimensions + array.dimensions;
basic_type = array.basic_type;
break;
case Constants.T_VOID:
throw new ClassGenException("Invalid type: void[]");
default: // Basic type or reference
this.dimensions = dimensions;
basic_type = type;
break;
}
StringBuffer buf = new StringBuffer();
for (int i = 0; i < this.dimensions; i++) {
buf.append('[');
}
buf.append(basic_type.getSignature());
signature = buf.toString();
}
/**
* @return a hash code value for the object.
*/
@Override
public int hashCode() {
return basic_type.hashCode() ^ dimensions;
}
/** /**
* @return basic type of array, i.e., for int[][][] the basic type is int * @return true if both type objects refer to the same array type.
*/ */
public Type getBasicType() { @Override
return basic_type; public boolean equals(Object _type) {
} if (_type instanceof ArrayType) {
ArrayType array = (ArrayType) _type;
return (array.dimensions == dimensions)
/** && array.basic_type.equals(basic_type);
* @return element type of array, i.e., for int[][][] the element type is int[][] }
*/ return false;
public Type getElementType() { }
if (dimensions == 1) {
return basic_type;
}
return new ArrayType(basic_type, dimensions - 1);
}
/** @return number of dimensions of array
*/
public int getDimensions() {
return dimensions;
}
/** @return a hash code value for the object.
*/
public int hashCode() {
return basic_type.hashCode() ^ dimensions;
}
/** @return true if both type objects refer to the same array type.
*/
public boolean equals( Object _type ) {
if (_type instanceof ArrayType) {
ArrayType array = (ArrayType) _type;
return (array.dimensions == dimensions) && array.basic_type.equals(basic_type);
}
return false;
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* BALOAD - Load byte or boolean from array * BALOAD - Load byte or boolean from array
* <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE> *
* * <PRE>
* Stack: ..., arrayref, index -&gt; ..., value
* </PRE>
*
* @version $Id: BALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: BALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class BALOAD extends ArrayInstruction implements StackProducer { public class BALOAD extends ArrayInstruction implements StackProducer {
/** Load byte or boolean from array /**
*/ *
public BALOAD() { */
super(org.apache.bcel.Constants.BALOAD); private static final long serialVersionUID = 1L;
}
/**
* Load byte or boolean from array
*/
public BALOAD() {
super(org.apache.bcel.Constants.BALOAD);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitStackProducer(this); @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitTypedInstruction(this); v.visitStackProducer(this);
v.visitArrayInstruction(this); v.visitExceptionThrower(this);
v.visitBALOAD(this); v.visitTypedInstruction(this);
} v.visitArrayInstruction(this);
v.visitBALOAD(this);
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* BASTORE - Store into byte or boolean array * BASTORE - Store into byte or boolean array
* <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE> *
* * <PRE>
* Stack: ..., arrayref, index, value -&gt; ...
* </PRE>
*
* @version $Id: BASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: BASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class BASTORE extends ArrayInstruction implements StackConsumer { public class BASTORE extends ArrayInstruction implements StackConsumer {
/** Store byte or boolean into array /**
*/ *
public BASTORE() { */
super(org.apache.bcel.Constants.BASTORE); private static final long serialVersionUID = 1L;
}
/**
* Store byte or boolean into array
*/
public BASTORE() {
super(org.apache.bcel.Constants.BASTORE);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitStackConsumer(this); @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitTypedInstruction(this); v.visitStackConsumer(this);
v.visitArrayInstruction(this); v.visitExceptionThrower(this);
v.visitBASTORE(this); v.visitTypedInstruction(this);
} v.visitArrayInstruction(this);
v.visitBASTORE(this);
}
} }

View File

@ -20,86 +20,94 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.util.ByteSequence; import org.apache.bcel.util.ByteSequence;
/** /**
* BIPUSH - Push byte on stack * BIPUSH - Push byte on stack
* *
* <PRE>Stack: ... -&gt; ..., value</PRE> * <PRE>
* * Stack: ... -&gt; ..., value
* </PRE>
*
* @version $Id: BIPUSH.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: BIPUSH.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class BIPUSH extends Instruction implements ConstantPushInstruction { public class BIPUSH extends Instruction implements ConstantPushInstruction {
private byte b; /**
*
*/
private static final long serialVersionUID = 1L;
private byte b;
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
BIPUSH() {
}
/** /**
* Empty constructor needed for the Class.newInstance() statement in * Push byte on stack
* Instruction.readInstruction(). Not to be used otherwise. */
*/ public BIPUSH(byte b) {
BIPUSH() { super(org.apache.bcel.Constants.BIPUSH, (short) 2);
} this.b = b;
}
/**
* Dump instruction as byte code to stream out.
*/
@Override
public void dump(DataOutputStream out) throws IOException {
super.dump(out);
out.writeByte(b);
}
/** Push byte on stack /**
*/ * @return mnemonic for instruction
public BIPUSH(byte b) { */
super(org.apache.bcel.Constants.BIPUSH, (short) 2); @Override
this.b = b; public String toString(boolean verbose) {
} return super.toString(verbose) + " " + b;
}
/**
* Read needed data (e.g. index) from file.
*/
@Override
protected void initFromFile(ByteSequence bytes, boolean wide)
throws IOException {
length = 2;
b = bytes.readByte();
}
/** @Override
* Dump instruction as byte code to stream out. public Number getValue() {
*/ return new Integer(b);
public void dump( DataOutputStream out ) throws IOException { }
super.dump(out);
out.writeByte(b);
}
/**
* @return Type.BYTE
*/
@Override
public Type getType(ConstantPoolGen cp) {
return Type.BYTE;
}
/** /**
* @return mnemonic for instruction * Call corresponding visitor method(s). The order is: Call visitor methods
*/ * of implemented interfaces first, then call methods according to the class
public String toString( boolean verbose ) { * hierarchy in descending order, i.e., the most specific visitXXX() call
return super.toString(verbose) + " " + b; * comes last.
} *
* @param v
* Visitor object
/** */
* Read needed data (e.g. index) from file. @Override
*/ public void accept(Visitor v) {
protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { v.visitPushInstruction(this);
length = 2; v.visitStackProducer(this);
b = bytes.readByte(); v.visitTypedInstruction(this);
} v.visitConstantPushInstruction(this);
v.visitBIPUSH(this);
}
public Number getValue() {
return new Integer(b);
}
/** @return Type.BYTE
*/
public Type getType( ConstantPoolGen cp ) {
return Type.BYTE;
}
/**
* Call corresponding visitor method(s). The order is:
* Call visitor methods of implemented interfaces first, then
* call methods according to the class hierarchy in descending order,
* i.e., the most specific visitXXX() call comes last.
*
* @param v Visitor object
*/
public void accept( Visitor v ) {
v.visitPushInstruction(this);
v.visitStackProducer(this);
v.visitTypedInstruction(this);
v.visitConstantPushInstruction(this);
v.visitBIPUSH(this);
}
} }

View File

@ -18,26 +18,32 @@ package org.apache.bcel.generic;
/** /**
* BREAKPOINT, JVM dependent, ignored by default * BREAKPOINT, JVM dependent, ignored by default
* *
* @version $Id: BREAKPOINT.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: BREAKPOINT.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class BREAKPOINT extends Instruction { public class BREAKPOINT extends Instruction {
public BREAKPOINT() { /**
super(org.apache.bcel.Constants.BREAKPOINT, (short) 1); *
} */
private static final long serialVersionUID = 1L;
public BREAKPOINT() {
super(org.apache.bcel.Constants.BREAKPOINT, (short) 1);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitBREAKPOINT(this); @Override
} public void accept(Visitor v) {
v.visitBREAKPOINT(this);
}
} }

View File

@ -18,64 +18,72 @@ package org.apache.bcel.generic;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
/** /**
* Denotes basic type such as int. * Denotes basic type such as int.
* *
* @version $Id: BasicType.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: BasicType.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class BasicType extends Type { public final class BasicType extends Type {
/** /**
* Constructor for basic types such as int, long, `void' *
* */
* @param type one of T_INT, T_BOOLEAN, ..., T_VOID private static final long serialVersionUID = 1L;
* @see org.apache.bcel.Constants
*/
BasicType(byte type) {
super(type, Constants.SHORT_TYPE_NAMES[type]);
if ((type < Constants.T_BOOLEAN) || (type > Constants.T_VOID)) {
throw new ClassGenException("Invalid type: " + type);
}
}
/**
* Constructor for basic types such as int, long, `void'
*
* @param type
* one of T_INT, T_BOOLEAN, ..., T_VOID
* @see org.apache.bcel.Constants
*/
BasicType(byte type) {
super(type, Constants.SHORT_TYPE_NAMES[type]);
if ((type < Constants.T_BOOLEAN) || (type > Constants.T_VOID)) {
throw new ClassGenException("Invalid type: " + type);
}
}
public static final BasicType getType( byte type ) { public static final BasicType getType(byte type) {
switch (type) { switch (type) {
case Constants.T_VOID: case Constants.T_VOID:
return VOID; return VOID;
case Constants.T_BOOLEAN: case Constants.T_BOOLEAN:
return BOOLEAN; return BOOLEAN;
case Constants.T_BYTE: case Constants.T_BYTE:
return BYTE; return BYTE;
case Constants.T_SHORT: case Constants.T_SHORT:
return SHORT; return SHORT;
case Constants.T_CHAR: case Constants.T_CHAR:
return CHAR; return CHAR;
case Constants.T_INT: case Constants.T_INT:
return INT; return INT;
case Constants.T_LONG: case Constants.T_LONG:
return LONG; return LONG;
case Constants.T_DOUBLE: case Constants.T_DOUBLE:
return DOUBLE; return DOUBLE;
case Constants.T_FLOAT: case Constants.T_FLOAT:
return FLOAT; return FLOAT;
default: default:
throw new ClassGenException("Invalid type: " + type); throw new ClassGenException("Invalid type: " + type);
} }
} }
/**
* @return a hash code value for the object.
*/
@Override
public int hashCode() {
return type;
}
/** @return a hash code value for the object. /**
*/ * @return true if both type objects refer to the same type
public int hashCode() { */
return type; @Override
} public boolean equals(Object _type) {
return (_type instanceof BasicType) ? ((BasicType) _type).type == this.type
: false;
/** @return true if both type objects refer to the same type }
*/
public boolean equals( Object _type ) {
return (_type instanceof BasicType) ? ((BasicType) _type).type == this.type : false;
}
} }

View File

@ -19,103 +19,106 @@ package org.apache.bcel.generic;
/** /**
* BranchHandle is returned by specialized InstructionList.append() whenever a * BranchHandle is returned by specialized InstructionList.append() whenever a
* BranchInstruction is appended. This is useful when the target of this * BranchInstruction is appended. This is useful when the target of this
* instruction is not known at time of creation and must be set later * instruction is not known at time of creation and must be set later via
* via setTarget(). * setTarget().
* *
* @see InstructionHandle * @see InstructionHandle
* @see Instruction * @see Instruction
* @see InstructionList * @see InstructionList
* @version $Id: BranchHandle.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: BranchHandle.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public final class BranchHandle extends InstructionHandle { public final class BranchHandle extends InstructionHandle {
private BranchInstruction bi; // An alias in fact, but saves lots of casts /**
*
*/
private static final long serialVersionUID = 1L;
private BranchInstruction bi; // An alias in fact, but saves lots of casts
private BranchHandle(BranchInstruction i) {
super(i);
bi = i;
}
private BranchHandle(BranchInstruction i) { /**
super(i); * Factory methods.
bi = i; */
} private static BranchHandle bh_list = null; // List of reusable handles
/** Factory methods. static final BranchHandle getBranchHandle(BranchInstruction i) {
*/ if (bh_list == null) {
private static BranchHandle bh_list = null; // List of reusable handles return new BranchHandle(i);
}
BranchHandle bh = bh_list;
bh_list = (BranchHandle) bh.next;
bh.setInstruction(i);
return bh;
}
/**
* Handle adds itself to the list of resuable handles.
*/
@Override
protected void addHandle() {
next = bh_list;
bh_list = this;
}
static final BranchHandle getBranchHandle( BranchInstruction i ) { /*
if (bh_list == null) { * Override InstructionHandle methods: delegate to branch instruction.
return new BranchHandle(i); * Through this overriding all access to the private i_position field should
} * be prevented.
BranchHandle bh = bh_list; */
bh_list = (BranchHandle) bh.next; @Override
bh.setInstruction(i); public int getPosition() {
return bh; return bi.position;
} }
@Override
void setPosition(int pos) {
i_position = bi.position = pos;
}
/** Handle adds itself to the list of resuable handles. @Override
*/ protected int updatePosition(int offset, int max_offset) {
protected void addHandle() { int x = bi.updatePosition(offset, max_offset);
next = bh_list; i_position = bi.position;
bh_list = this; return x;
} }
/**
* Pass new target to instruction.
*/
public void setTarget(InstructionHandle ih) {
bi.setTarget(ih);
}
/* Override InstructionHandle methods: delegate to branch instruction. /**
* Through this overriding all access to the private i_position field should * Update target of instruction.
* be prevented. */
*/ public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
public int getPosition() { bi.updateTarget(old_ih, new_ih);
return bi.position; }
}
/**
* @return target of instruction.
*/
public InstructionHandle getTarget() {
return bi.getTarget();
}
void setPosition( int pos ) { /**
i_position = bi.position = pos; * Set new contents. Old instruction is disposed and may not be used
} * anymore.
*/
@Override
protected int updatePosition( int offset, int max_offset ) { public void setInstruction(Instruction i) {
int x = bi.updatePosition(offset, max_offset); super.setInstruction(i);
i_position = bi.position; if (!(i instanceof BranchInstruction)) {
return x; throw new ClassGenException("Assigning " + i
} + " to branch handle which is not a branch instruction");
}
bi = (BranchInstruction) i;
/** }
* Pass new target to instruction.
*/
public void setTarget( InstructionHandle ih ) {
bi.setTarget(ih);
}
/**
* Update target of instruction.
*/
public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
bi.updateTarget(old_ih, new_ih);
}
/**
* @return target of instruction.
*/
public InstructionHandle getTarget() {
return bi.getTarget();
}
/**
* Set new contents. Old instruction is disposed and may not be used anymore.
*/
public void setInstruction( Instruction i ) {
super.setInstruction(i);
if (!(i instanceof BranchInstruction)) {
throw new ClassGenException("Assigning " + i
+ " to branch handle which is not a branch instruction");
}
bi = (BranchInstruction) i;
}
} }

View File

@ -20,211 +20,230 @@ import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import org.apache.bcel.util.ByteSequence; import org.apache.bcel.util.ByteSequence;
/** /**
* Abstract super class for branching instructions like GOTO, IFEQ, etc.. * Abstract super class for branching instructions like GOTO, IFEQ, etc.. Branch
* Branch instructions may have a variable length, namely GOTO, JSR, * instructions may have a variable length, namely GOTO, JSR, LOOKUPSWITCH and
* LOOKUPSWITCH and TABLESWITCH. * TABLESWITCH.
* *
* @see InstructionList * @see InstructionList
* @version $Id: BranchInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: BranchInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class BranchInstruction extends Instruction implements InstructionTargeter { public abstract class BranchInstruction extends Instruction implements
InstructionTargeter {
protected int index; // Branch target relative to this instruction /**
protected InstructionHandle target; // Target object in instruction list *
protected int position; // Byte code offset */
private static final long serialVersionUID = 1L;
protected int index; // Branch target relative to this instruction
protected InstructionHandle target; // Target object in instruction list
protected int position; // Byte code offset
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
BranchInstruction() {
}
/** /**
* Empty constructor needed for the Class.newInstance() statement in * Common super constructor
* Instruction.readInstruction(). Not to be used otherwise. *
*/ * @param opcode
BranchInstruction() { * Instruction opcode
} * @param target
* instruction to branch to
*/
protected BranchInstruction(short opcode, InstructionHandle target) {
super(opcode, (short) 3);
setTarget(target);
}
/**
* Dump instruction as byte code to stream out.
*
* @param out
* Output stream
*/
@Override
public void dump(DataOutputStream out) throws IOException {
out.writeByte(opcode);
index = getTargetOffset();
if (Math.abs(index) >= 32767) {
throw new ClassGenException(
"Branch target offset too large for short");
}
out.writeShort(index); // May be negative, i.e., point backwards
}
/** Common super constructor /**
* @param opcode Instruction opcode * @param _target
* @param target instruction to branch to * branch target
*/ * @return the offset to `target' relative to this instruction
protected BranchInstruction(short opcode, InstructionHandle target) { */
super(opcode, (short) 3); protected int getTargetOffset(InstructionHandle _target) {
setTarget(target); if (_target == null) {
} throw new ClassGenException("Target of " + super.toString(true)
+ " is invalid null handle");
}
int t = _target.getPosition();
if (t < 0) {
throw new ClassGenException(
"Invalid branch target position offset for "
+ super.toString(true) + ":" + t + ":" + _target);
}
return t - position;
}
/**
* @return the offset to this instruction's target
*/
protected int getTargetOffset() {
return getTargetOffset(target);
}
/** /**
* Dump instruction as byte code to stream out. * Called by InstructionList.setPositions when setting the position for
* @param out Output stream * every instruction. In the presence of variable length instructions
*/ * `setPositions' performs multiple passes over the instruction list to
public void dump( DataOutputStream out ) throws IOException { * calculate the correct (byte) positions and offsets by calling this
out.writeByte(opcode); * function.
index = getTargetOffset(); *
if (Math.abs(index) >= 32767) { * @param offset
throw new ClassGenException("Branch target offset too large for short"); * additional offset caused by preceding (variable length)
} * instructions
out.writeShort(index); // May be negative, i.e., point backwards * @param max_offset
} * the maximum offset that may be caused by these instructions
* @return additional offset caused by possible change of this instruction's
* length
*/
protected int updatePosition(int offset, int max_offset) {
position += offset;
return 0;
}
/**
* Long output format:
*
* &lt;position in byte code&gt; &lt;name of opcode&gt; "["&lt;opcode
* number&gt;"]" "("&lt;length of instruction&gt;")" "&lt;"&lt;target
* instruction&gt;"&gt;" "@"&lt;branch target offset&gt;
*
* @param verbose
* long/short format switch
* @return mnemonic for instruction
*/
@Override
public String toString(boolean verbose) {
String s = super.toString(verbose);
String t = "null";
if (verbose) {
if (target != null) {
if (target.getInstruction() == this) {
t = "<points to itself>";
} else if (target.getInstruction() == null) {
t = "<null instruction!!!?>";
} else {
t = target.getInstruction().toString(false); // Avoid
// circles
}
}
} else {
if (target != null) {
index = getTargetOffset();
t = "" + (index + position);
}
}
return s + " -> " + t;
}
/** /**
* @param _target branch target * Read needed data (e.g. index) from file. Conversion to a
* @return the offset to `target' relative to this instruction * InstructionHandle is done in InstructionList(byte[]).
*/ *
protected int getTargetOffset( InstructionHandle _target ) { * @param bytes
if (_target == null) { * input stream
throw new ClassGenException("Target of " + super.toString(true) * @param wide
+ " is invalid null handle"); * wide prefix?
} * @see InstructionList
int t = _target.getPosition(); */
if (t < 0) { @Override
throw new ClassGenException("Invalid branch target position offset for " protected void initFromFile(ByteSequence bytes, boolean wide)
+ super.toString(true) + ":" + t + ":" + _target); throws IOException {
} length = 3;
return t - position; index = bytes.readShort();
} }
/**
* @return target offset in byte code
*/
public final int getIndex() {
return index;
}
/** /**
* @return the offset to this instruction's target * @return target of branch instruction
*/ */
protected int getTargetOffset() { public InstructionHandle getTarget() {
return getTargetOffset(target); return target;
} }
/**
* Set branch target
*
* @param target
* branch target
*/
public void setTarget(InstructionHandle target) {
notifyTarget(this.target, target, this);
this.target = target;
}
/** /**
* Called by InstructionList.setPositions when setting the position for every * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen
* instruction. In the presence of variable length instructions `setPositions' */
* performs multiple passes over the instruction list to calculate the static final void notifyTarget(InstructionHandle old_ih,
* correct (byte) positions and offsets by calling this function. InstructionHandle new_ih, InstructionTargeter t) {
* if (old_ih != null) {
* @param offset additional offset caused by preceding (variable length) instructions old_ih.removeTargeter(t);
* @param max_offset the maximum offset that may be caused by these instructions }
* @return additional offset caused by possible change of this instruction's length if (new_ih != null) {
*/ new_ih.addTargeter(t);
protected int updatePosition( int offset, int max_offset ) { }
position += offset; }
return 0;
}
/**
* @param old_ih
* old target
* @param new_ih
* new target
*/
@Override
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
if (target == old_ih) {
setTarget(new_ih);
} else {
throw new ClassGenException("Not targeting " + old_ih + ", but "
+ target);
}
}
/** /**
* Long output format: * @return true, if ih is target of this instruction
* */
* &lt;position in byte code&gt; @Override
* &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" public boolean containsTarget(InstructionHandle ih) {
* "("&lt;length of instruction&gt;")" return (target == ih);
* "&lt;"&lt;target instruction&gt;"&gt;" "@"&lt;branch target offset&gt; }
*
* @param verbose long/short format switch
* @return mnemonic for instruction
*/
public String toString( boolean verbose ) {
String s = super.toString(verbose);
String t = "null";
if (verbose) {
if (target != null) {
if (target.getInstruction() == this) {
t = "<points to itself>";
} else if (target.getInstruction() == null) {
t = "<null instruction!!!?>";
} else {
t = target.getInstruction().toString(false); // Avoid circles
}
}
} else {
if (target != null) {
index = getTargetOffset();
t = "" + (index + position);
}
}
return s + " -> " + t;
}
/**
/** * Inform target that it's not targeted anymore.
* Read needed data (e.g. index) from file. Conversion to a InstructionHandle */
* is done in InstructionList(byte[]). @Override
* void dispose() {
* @param bytes input stream setTarget(null);
* @param wide wide prefix? index = -1;
* @see InstructionList position = -1;
*/ }
protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
length = 3;
index = bytes.readShort();
}
/**
* @return target offset in byte code
*/
public final int getIndex() {
return index;
}
/**
* @return target of branch instruction
*/
public InstructionHandle getTarget() {
return target;
}
/**
* Set branch target
* @param target branch target
*/
public void setTarget( InstructionHandle target ) {
notifyTarget(this.target, target, this);
this.target = target;
}
/**
* Used by BranchInstruction, LocalVariableGen, CodeExceptionGen
*/
static final void notifyTarget( InstructionHandle old_ih, InstructionHandle new_ih,
InstructionTargeter t ) {
if (old_ih != null) {
old_ih.removeTargeter(t);
}
if (new_ih != null) {
new_ih.addTargeter(t);
}
}
/**
* @param old_ih old target
* @param new_ih new target
*/
public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
if (target == old_ih) {
setTarget(new_ih);
} else {
throw new ClassGenException("Not targeting " + old_ih + ", but " + target);
}
}
/**
* @return true, if ih is target of this instruction
*/
public boolean containsTarget( InstructionHandle ih ) {
return (target == ih);
}
/**
* Inform target that it's not targeted anymore.
*/
void dispose() {
setTarget(null);
index = -1;
position = -1;
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* CALOAD - Load char from array * CALOAD - Load char from array
* <PRE>Stack: ..., arrayref, index -&gt; ..., value</PRE> *
* * <PRE>
* Stack: ..., arrayref, index -&gt; ..., value
* </PRE>
*
* @version $Id: CALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: CALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class CALOAD extends ArrayInstruction implements StackProducer { public class CALOAD extends ArrayInstruction implements StackProducer {
/** Load char from array /**
*/ *
public CALOAD() { */
super(org.apache.bcel.Constants.CALOAD); private static final long serialVersionUID = 1L;
}
/**
* Load char from array
*/
public CALOAD() {
super(org.apache.bcel.Constants.CALOAD);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitStackProducer(this); @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitTypedInstruction(this); v.visitStackProducer(this);
v.visitArrayInstruction(this); v.visitExceptionThrower(this);
v.visitCALOAD(this); v.visitTypedInstruction(this);
} v.visitArrayInstruction(this);
v.visitCALOAD(this);
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* CASTORE - Store into char array * CASTORE - Store into char array
* <PRE>Stack: ..., arrayref, index, value -&gt; ...</PRE> *
* * <PRE>
* Stack: ..., arrayref, index, value -&gt; ...
* </PRE>
*
* @version $Id: CASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: CASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class CASTORE extends ArrayInstruction implements StackConsumer { public class CASTORE extends ArrayInstruction implements StackConsumer {
/** Store char into array /**
*/ *
public CASTORE() { */
super(org.apache.bcel.Constants.CASTORE); private static final long serialVersionUID = 1L;
}
/**
* Store char into array
*/
public CASTORE() {
super(org.apache.bcel.Constants.CASTORE);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitStackConsumer(this); @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitTypedInstruction(this); v.visitStackConsumer(this);
v.visitArrayInstruction(this); v.visitExceptionThrower(this);
v.visitCASTORE(this); v.visitTypedInstruction(this);
} v.visitArrayInstruction(this);
v.visitCASTORE(this);
}
} }

View File

@ -18,67 +18,81 @@ package org.apache.bcel.generic;
import org.apache.bcel.ExceptionConstants; import org.apache.bcel.ExceptionConstants;
/** /**
* CHECKCAST - Check whether object is of given type * CHECKCAST - Check whether object is of given type
* <PRE>Stack: ..., objectref -&gt; ..., objectref</PRE> *
* * <PRE>
* Stack: ..., objectref -&gt; ..., objectref
* </PRE>
*
* @version $Id: CHECKCAST.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: CHECKCAST.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class CHECKCAST extends CPInstruction implements LoadClass, ExceptionThrower, StackProducer, public class CHECKCAST extends CPInstruction implements LoadClass,
StackConsumer { ExceptionThrower, StackProducer, StackConsumer {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
CHECKCAST() {
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
CHECKCAST() {
}
/** Check whether object is of given type /**
* @param index index to class in constant pool * Check whether object is of given type
*/ *
public CHECKCAST(int index) { * @param index
super(org.apache.bcel.Constants.CHECKCAST, index); * index to class in constant pool
} */
public CHECKCAST(int index) {
super(org.apache.bcel.Constants.CHECKCAST, index);
}
/**
* @return exceptions this instruction may cause
*/
@Override
public Class<?>[] getExceptions() {
Class<?>[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length];
System.arraycopy(
ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs,
0,
ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length);
cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.CLASS_CAST_EXCEPTION;
return cs;
}
/** @return exceptions this instruction may cause @Override
*/ public ObjectType getLoadClassType(ConstantPoolGen cpg) {
public Class[] getExceptions() { Type t = getType(cpg);
Class[] cs = new Class[1 + ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length]; if (t instanceof ArrayType) {
System.arraycopy(ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION, 0, cs, 0, t = ((ArrayType) t).getBasicType();
ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length); }
cs[ExceptionConstants.EXCS_CLASS_AND_INTERFACE_RESOLUTION.length] = ExceptionConstants.CLASS_CAST_EXCEPTION; return (t instanceof ObjectType) ? (ObjectType) t : null;
return cs; }
}
/**
public ObjectType getLoadClassType( ConstantPoolGen cpg ) { * Call corresponding visitor method(s). The order is: Call visitor methods
Type t = getType(cpg); * of implemented interfaces first, then call methods according to the class
if (t instanceof ArrayType) { * hierarchy in descending order, i.e., the most specific visitXXX() call
t = ((ArrayType) t).getBasicType(); * comes last.
} *
return (t instanceof ObjectType) ? (ObjectType) t : null; * @param v
} * Visitor object
*/
@Override
/** public void accept(Visitor v) {
* Call corresponding visitor method(s). The order is: v.visitLoadClass(this);
* Call visitor methods of implemented interfaces first, then v.visitExceptionThrower(this);
* call methods according to the class hierarchy in descending order, v.visitStackProducer(this);
* i.e., the most specific visitXXX() call comes last. v.visitStackConsumer(this);
* v.visitTypedInstruction(this);
* @param v Visitor object v.visitCPInstruction(this);
*/ v.visitCHECKCAST(this);
public void accept( Visitor v ) { }
v.visitLoadClass(this);
v.visitExceptionThrower(this);
v.visitStackProducer(this);
v.visitStackConsumer(this);
v.visitTypedInstruction(this);
v.visitCPInstruction(this);
v.visitCHECKCAST(this);
}
} }

View File

@ -23,116 +23,130 @@ import org.apache.bcel.classfile.ConstantClass;
import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.util.ByteSequence; import org.apache.bcel.util.ByteSequence;
/** /**
* Abstract super class for instructions that use an index into the * Abstract super class for instructions that use an index into the constant
* constant pool such as LDC, INVOKEVIRTUAL, etc. * pool such as LDC, INVOKEVIRTUAL, etc.
* *
* @see ConstantPoolGen * @see ConstantPoolGen
* @see LDC * @see LDC
* @see INVOKEVIRTUAL * @see INVOKEVIRTUAL
* *
* @version $Id: CPInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: CPInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class CPInstruction extends Instruction implements TypedInstruction, public abstract class CPInstruction extends Instruction implements
IndexedInstruction { TypedInstruction, IndexedInstruction {
protected int index; // index to constant pool /**
*
*/
private static final long serialVersionUID = 1L;
protected int index; // index to constant pool
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
CPInstruction() {
}
/** /**
* Empty constructor needed for the Class.newInstance() statement in * @param index
* Instruction.readInstruction(). Not to be used otherwise. * to constant pool
*/ */
CPInstruction() { protected CPInstruction(short opcode, int index) {
} super(opcode, (short) 3);
setIndex(index);
}
/**
* Dump instruction as byte code to stream out.
*
* @param out
* Output stream
*/
@Override
public void dump(DataOutputStream out) throws IOException {
out.writeByte(opcode);
out.writeShort(index);
}
/** /**
* @param index to constant pool * Long output format:
*/ *
protected CPInstruction(short opcode, int index) { * &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" "("&lt;length of
super(opcode, (short) 3); * instruction&gt;")" "&lt;"&lt; constant pool index&gt;"&gt;"
setIndex(index); *
} * @param verbose
* long/short format switch
* @return mnemonic for instruction
*/
@Override
public String toString(boolean verbose) {
return super.toString(verbose) + " " + index;
}
/**
* @return mnemonic for instruction with symbolic references resolved
*/
@Override
public String toString(ConstantPool cp) {
Constant c = cp.getConstant(index);
String str = cp.constantToString(c);
if (c instanceof ConstantClass) {
str = str.replace('.', '/');
}
return org.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + str;
}
/** /**
* Dump instruction as byte code to stream out. * Read needed data (i.e., index) from file.
* @param out Output stream *
*/ * @param bytes
public void dump( DataOutputStream out ) throws IOException { * input stream
out.writeByte(opcode); * @param wide
out.writeShort(index); * wide prefix?
} */
@Override
protected void initFromFile(ByteSequence bytes, boolean wide)
throws IOException {
setIndex(bytes.readUnsignedShort());
length = 3;
}
/**
* @return index in constant pool referred by this instruction.
*/
@Override
public final int getIndex() {
return index;
}
/** /**
* Long output format: * Set the index to constant pool.
* *
* &lt;name of opcode&gt; "["&lt;opcode number&gt;"]" * @param index
* "("&lt;length of instruction&gt;")" "&lt;"&lt; constant pool index&gt;"&gt;" * in constant pool.
* */
* @param verbose long/short format switch @Override
* @return mnemonic for instruction public void setIndex(int index) {
*/ if (index < 0) {
public String toString( boolean verbose ) { throw new ClassGenException("Negative index value: " + index);
return super.toString(verbose) + " " + index; }
} this.index = index;
}
/**
/** * @return type related with this instruction.
* @return mnemonic for instruction with symbolic references resolved */
*/ @Override
public String toString( ConstantPool cp ) { public Type getType(ConstantPoolGen cpg) {
Constant c = cp.getConstant(index); ConstantPool cp = cpg.getConstantPool();
String str = cp.constantToString(c); String name = cp.getConstantString(index,
if (c instanceof ConstantClass) { org.apache.bcel.Constants.CONSTANT_Class);
str = str.replace('.', '/'); if (!name.startsWith("[")) {
} name = "L" + name + ";";
return org.apache.bcel.Constants.OPCODE_NAMES[opcode] + " " + str; }
} return Type.getType(name);
}
/**
* Read needed data (i.e., index) from file.
* @param bytes input stream
* @param wide wide prefix?
*/
protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
setIndex(bytes.readUnsignedShort());
length = 3;
}
/**
* @return index in constant pool referred by this instruction.
*/
public final int getIndex() {
return index;
}
/**
* Set the index to constant pool.
* @param index in constant pool.
*/
public void setIndex( int index ) {
if (index < 0) {
throw new ClassGenException("Negative index value: " + index);
}
this.index = index;
}
/** @return type related with this instruction.
*/
public Type getType( ConstantPoolGen cpg ) {
ConstantPool cp = cpg.getConstantPool();
String name = cp.getConstantString(index, org.apache.bcel.Constants.CONSTANT_Class);
if (!name.startsWith("[")) {
name = "L" + name + ";";
}
return Type.getType(name);
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -16,21 +16,25 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* Thrown on internal errors. Extends RuntimeException so it hasn't to be declared * Thrown on internal errors. Extends RuntimeException so it hasn't to be
* in the throws clause every time. * declared in the throws clause every time.
* *
* @version $Id: ClassGenException.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ClassGenException.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class ClassGenException extends RuntimeException { public class ClassGenException extends RuntimeException {
public ClassGenException() { /**
super(); *
} */
private static final long serialVersionUID = 1L;
public ClassGenException() {
super();
}
public ClassGenException(String s) { public ClassGenException(String s) {
super(s); super(s);
} }
} }

View File

@ -19,11 +19,11 @@ package org.apache.bcel.generic;
/** /**
* Implement this interface if you're interested in changes to a ClassGen object * Implement this interface if you're interested in changes to a ClassGen object
* and register yourself with addObserver(). * and register yourself with addObserver().
* *
* @version $Id: ClassObserver.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ClassObserver.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public interface ClassObserver { public interface ClassObserver {
public void notify( ClassGen clazz ); public void notify(ClassGen clazz);
} }

View File

@ -18,167 +18,181 @@ package org.apache.bcel.generic;
import org.apache.bcel.classfile.CodeException; import org.apache.bcel.classfile.CodeException;
/** /**
* This class represents an exception handler, i.e., specifies the region where * This class represents an exception handler, i.e., specifies the region where
* a handler is active and an instruction where the actual handling is done. * a handler is active and an instruction where the actual handling is done.
* pool as parameters. Opposed to the JVM specification the end of the handled * pool as parameters. Opposed to the JVM specification the end of the handled
* region is set to be inclusive, i.e. all instructions between start and end * region is set to be inclusive, i.e. all instructions between start and end
* are protected including the start and end instructions (handles) themselves. * are protected including the start and end instructions (handles) themselves.
* The end of the region is automatically mapped to be exclusive when calling * The end of the region is automatically mapped to be exclusive when calling
* getCodeException(), i.e., there is no difference semantically. * getCodeException(), i.e., there is no difference semantically.
* *
* @version $Id: CodeExceptionGen.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: CodeExceptionGen.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see MethodGen * @see MethodGen
* @see CodeException * @see CodeException
* @see InstructionHandle * @see InstructionHandle
*/ */
public final class CodeExceptionGen implements InstructionTargeter, Cloneable, java.io.Serializable { public final class CodeExceptionGen implements InstructionTargeter, Cloneable,
java.io.Serializable {
private InstructionHandle start_pc; /**
private InstructionHandle end_pc; *
private InstructionHandle handler_pc; */
private ObjectType catch_type; private static final long serialVersionUID = 1L;
private InstructionHandle start_pc;
private InstructionHandle end_pc;
private InstructionHandle handler_pc;
private ObjectType catch_type;
/**
* Add an exception handler, i.e., specify region where a handler is active
* and an instruction where the actual handling is done.
*
* @param start_pc
* Start of handled region (inclusive)
* @param end_pc
* End of handled region (inclusive)
* @param handler_pc
* Where handling is done
* @param catch_type
* which exception is handled, null for ANY
*/
public CodeExceptionGen(InstructionHandle start_pc,
InstructionHandle end_pc, InstructionHandle handler_pc,
ObjectType catch_type) {
setStartPC(start_pc);
setEndPC(end_pc);
setHandlerPC(handler_pc);
this.catch_type = catch_type;
}
/** /**
* Add an exception handler, i.e., specify region where a handler is active and an * Get CodeException object.<BR>
* instruction where the actual handling is done. *
* * This relies on that the instruction list has already been dumped to byte
* @param start_pc Start of handled region (inclusive) * code or or that the `setPositions' methods has been called for the
* @param end_pc End of handled region (inclusive) * instruction list.
* @param handler_pc Where handling is done *
* @param catch_type which exception is handled, null for ANY * @param cp
*/ * constant pool
public CodeExceptionGen(InstructionHandle start_pc, InstructionHandle end_pc, */
InstructionHandle handler_pc, ObjectType catch_type) { public CodeException getCodeException(ConstantPoolGen cp) {
setStartPC(start_pc); return new CodeException(start_pc.getPosition(), end_pc.getPosition()
setEndPC(end_pc); + end_pc.getInstruction().getLength(),
setHandlerPC(handler_pc); handler_pc.getPosition(), (catch_type == null) ? 0
this.catch_type = catch_type; : cp.addClass(catch_type));
} }
/*
* Set start of handler
*
* @param start_pc Start of handled region (inclusive)
*/
public void setStartPC(InstructionHandle start_pc) {
BranchInstruction.notifyTarget(this.start_pc, start_pc, this);
this.start_pc = start_pc;
}
/** /*
* Get CodeException object.<BR> * Set end of handler
* *
* This relies on that the instruction list has already been dumped * @param end_pc End of handled region (inclusive)
* to byte code or or that the `setPositions' methods has been */
* called for the instruction list. public void setEndPC(InstructionHandle end_pc) {
* BranchInstruction.notifyTarget(this.end_pc, end_pc, this);
* @param cp constant pool this.end_pc = end_pc;
*/ }
public CodeException getCodeException( ConstantPoolGen cp ) {
return new CodeException(start_pc.getPosition(), end_pc.getPosition()
+ end_pc.getInstruction().getLength(), handler_pc.getPosition(),
(catch_type == null) ? 0 : cp.addClass(catch_type));
}
/*
* Set handler code
*
* @param handler_pc Start of handler
*/
public void setHandlerPC(InstructionHandle handler_pc) {
BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this);
this.handler_pc = handler_pc;
}
/* Set start of handler /**
* @param start_pc Start of handled region (inclusive) * @param old_ih
*/ * old target, either start or end
public void setStartPC( InstructionHandle start_pc ) { * @param new_ih
BranchInstruction.notifyTarget(this.start_pc, start_pc, this); * new target
this.start_pc = start_pc; */
} @Override
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
boolean targeted = false;
if (start_pc == old_ih) {
targeted = true;
setStartPC(new_ih);
}
if (end_pc == old_ih) {
targeted = true;
setEndPC(new_ih);
}
if (handler_pc == old_ih) {
targeted = true;
setHandlerPC(new_ih);
}
if (!targeted) {
throw new ClassGenException("Not targeting " + old_ih + ", but {"
+ start_pc + ", " + end_pc + ", " + handler_pc + "}");
}
}
/**
* @return true, if ih is target of this handler
*/
@Override
public boolean containsTarget(InstructionHandle ih) {
return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih);
}
/* Set end of handler /** Sets the type of the Exception to catch. Set 'null' for ANY. */
* @param end_pc End of handled region (inclusive) public void setCatchType(ObjectType catch_type) {
*/ this.catch_type = catch_type;
public void setEndPC( InstructionHandle end_pc ) { }
BranchInstruction.notifyTarget(this.end_pc, end_pc, this);
this.end_pc = end_pc;
}
/** Gets the type of the Exception to catch, 'null' for ANY. */
public ObjectType getCatchType() {
return catch_type;
}
/* Set handler code /**
* @param handler_pc Start of handler * @return start of handled region (inclusive)
*/ */
public void setHandlerPC( InstructionHandle handler_pc ) { public InstructionHandle getStartPC() {
BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this); return start_pc;
this.handler_pc = handler_pc; }
}
/**
* @return end of handled region (inclusive)
*/
public InstructionHandle getEndPC() {
return end_pc;
}
/** /**
* @param old_ih old target, either start or end * @return start of handler
* @param new_ih new target */
*/ public InstructionHandle getHandlerPC() {
public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) { return handler_pc;
boolean targeted = false; }
if (start_pc == old_ih) {
targeted = true;
setStartPC(new_ih);
}
if (end_pc == old_ih) {
targeted = true;
setEndPC(new_ih);
}
if (handler_pc == old_ih) {
targeted = true;
setHandlerPC(new_ih);
}
if (!targeted) {
throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", "
+ end_pc + ", " + handler_pc + "}");
}
}
@Override
public String toString() {
return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", "
+ handler_pc + ")";
}
/** @Override
* @return true, if ih is target of this handler public Object clone() {
*/ try {
public boolean containsTarget( InstructionHandle ih ) { return super.clone();
return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); } catch (CloneNotSupportedException e) {
} System.err.println(e);
return null;
}
/** Sets the type of the Exception to catch. Set 'null' for ANY. */ }
public void setCatchType( ObjectType catch_type ) {
this.catch_type = catch_type;
}
/** Gets the type of the Exception to catch, 'null' for ANY. */
public ObjectType getCatchType() {
return catch_type;
}
/** @return start of handled region (inclusive)
*/
public InstructionHandle getStartPC() {
return start_pc;
}
/** @return end of handled region (inclusive)
*/
public InstructionHandle getEndPC() {
return end_pc;
}
/** @return start of handler
*/
public InstructionHandle getHandlerPC() {
return handler_pc;
}
public String toString() {
return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")";
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
System.err.println(e);
return null;
}
}
} }

View File

@ -17,22 +17,21 @@
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* Wrapper class for `compound' operations, virtual instructions that * Wrapper class for `compound' operations, virtual instructions that don't
* don't exist as byte code, but give a useful meaning. For example, * exist as byte code, but give a useful meaning. For example, the (virtual)
* the (virtual) PUSH instruction takes an arbitray argument and produces the * PUSH instruction takes an arbitray argument and produces the appropiate code
* appropiate code at dump time (ICONST, LDC, BIPUSH, ...). Also you can use the * at dump time (ICONST, LDC, BIPUSH, ...). Also you can use the SWITCH
* SWITCH instruction as a useful template for either LOOKUPSWITCH or * instruction as a useful template for either LOOKUPSWITCH or TABLESWITCH.
* TABLESWITCH. *
* * The interface provides the possibilty for the user to write `templates' or
* The interface provides the possibilty for the user to write * `macros' for such reuseable code patterns.
* `templates' or `macros' for such reuseable code patterns. *
*
* @version $Id: CompoundInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: CompoundInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see PUSH * @see PUSH
* @see SWITCH * @see SWITCH
*/ */
public interface CompoundInstruction { public interface CompoundInstruction {
public InstructionList getInstructionList(); public InstructionList getInstructionList();
} }

File diff suppressed because it is too large Load Diff

View File

@ -17,16 +17,18 @@
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* Denotes a push instruction that produces a literal on the stack * Denotes a push instruction that produces a literal on the stack such as
* such as SIPUSH, BIPUSH, ICONST, etc. * SIPUSH, BIPUSH, ICONST, etc.
* *
* @version $Id: ConstantPushInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConstantPushInstruction.java 386056 2006-03-15 11:31:56Z tcurdt
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*
* @see ICONST * @see ICONST
* @see SIPUSH * @see SIPUSH
*/ */
public interface ConstantPushInstruction extends PushInstruction, TypedInstruction { public interface ConstantPushInstruction extends PushInstruction,
TypedInstruction {
public Number getValue(); public Number getValue();
} }

View File

@ -20,57 +20,63 @@ import org.apache.bcel.Constants;
/** /**
* Super class for the x2y family of instructions. * Super class for the x2y family of instructions.
* *
* @version $Id: ConversionInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: ConversionInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public abstract class ConversionInstruction extends Instruction implements TypedInstruction, public abstract class ConversionInstruction extends Instruction implements
StackProducer, StackConsumer { TypedInstruction, StackProducer, StackConsumer {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
ConversionInstruction() {
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
ConversionInstruction() {
}
/** /**
* @param opcode opcode of instruction * @param opcode
*/ * opcode of instruction
protected ConversionInstruction(short opcode) { */
super(opcode, (short) 1); protected ConversionInstruction(short opcode) {
} super(opcode, (short) 1);
}
/**
/** @return type associated with the instruction * @return type associated with the instruction
*/ */
public Type getType( ConstantPoolGen cp ) { @Override
switch (opcode) { public Type getType(ConstantPoolGen cp) {
case Constants.D2I: switch (opcode) {
case Constants.F2I: case Constants.D2I:
case Constants.L2I: case Constants.F2I:
return Type.INT; case Constants.L2I:
case Constants.D2F: return Type.INT;
case Constants.I2F: case Constants.D2F:
case Constants.L2F: case Constants.I2F:
return Type.FLOAT; case Constants.L2F:
case Constants.D2L: return Type.FLOAT;
case Constants.F2L: case Constants.D2L:
case Constants.I2L: case Constants.F2L:
return Type.LONG; case Constants.I2L:
case Constants.F2D: return Type.LONG;
case Constants.I2D: case Constants.F2D:
case Constants.L2D: case Constants.I2D:
return Type.DOUBLE; case Constants.L2D:
case Constants.I2B: return Type.DOUBLE;
return Type.BYTE; case Constants.I2B:
case Constants.I2C: return Type.BYTE;
return Type.CHAR; case Constants.I2C:
case Constants.I2S: return Type.CHAR;
return Type.SHORT; case Constants.I2S:
default: // Never reached return Type.SHORT;
throw new ClassGenException("Unknown type " + opcode); default: // Never reached
} throw new ClassGenException("Unknown type " + opcode);
} }
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* D2F - Convert double to float * D2F - Convert double to float
* <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE> *
* * <PRE>
* Stack: ..., value.word1, value.word2 -&gt; ..., result
* </PRE>
*
* @version $Id: D2F.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: D2F.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class D2F extends ConversionInstruction { public class D2F extends ConversionInstruction {
/** Convert double to float /**
*/ *
public D2F() { */
super(org.apache.bcel.Constants.D2F); private static final long serialVersionUID = 1L;
}
/**
* Convert double to float
*/
public D2F() {
super(org.apache.bcel.Constants.D2F);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitConversionInstruction(this); v.visitStackProducer(this);
v.visitD2F(this); v.visitStackConsumer(this);
} v.visitConversionInstruction(this);
v.visitD2F(this);
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* D2I - Convert double to int * D2I - Convert double to int
* <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result</PRE> *
* * <PRE>
* Stack: ..., value.word1, value.word2 -&gt; ..., result
* </PRE>
*
* @version $Id: D2I.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: D2I.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class D2I extends ConversionInstruction { public class D2I extends ConversionInstruction {
/** Convert double to int /**
*/ *
public D2I() { */
super(org.apache.bcel.Constants.D2I); private static final long serialVersionUID = 1L;
}
/**
* Convert double to int
*/
public D2I() {
super(org.apache.bcel.Constants.D2I);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitConversionInstruction(this); v.visitStackProducer(this);
v.visitD2I(this); v.visitStackConsumer(this);
} v.visitConversionInstruction(this);
v.visitD2I(this);
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* D2L - Convert double to long * D2L - Convert double to long
* <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE> *
* * <PRE>
* Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2
* </PRE>
*
* @version $Id: D2L.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: D2L.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class D2L extends ConversionInstruction { public class D2L extends ConversionInstruction {
/** Convert double to long /**
*/ *
public D2L() { */
super(org.apache.bcel.Constants.D2L); private static final long serialVersionUID = 1L;
}
/**
* Convert double to long
*/
public D2L() {
super(org.apache.bcel.Constants.D2L);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitConversionInstruction(this); v.visitStackProducer(this);
v.visitD2L(this); v.visitStackConsumer(this);
} v.visitConversionInstruction(this);
v.visitD2L(this);
}
} }

View File

@ -16,36 +16,47 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DADD - Add doubles * DADD - Add doubles
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE> *
* ..., result.word1, result1.word2 * <PRE>
* * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;
* </PRE>
*
* ..., result.word1, result1.word2
*
* @version $Id: DADD.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DADD.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DADD extends ArithmeticInstruction { public class DADD extends ArithmeticInstruction {
/** Add doubles /**
*/ *
public DADD() { */
super(org.apache.bcel.Constants.DADD); private static final long serialVersionUID = 1L;
}
/**
* Add doubles
*/
public DADD() {
super(org.apache.bcel.Constants.DADD);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitArithmeticInstruction(this); v.visitStackProducer(this);
v.visitDADD(this); v.visitStackConsumer(this);
} v.visitArithmeticInstruction(this);
v.visitDADD(this);
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DALOAD - Load double from array * DALOAD - Load double from array
* <PRE>Stack: ..., arrayref, index -&gt; ..., result.word1, result.word2</PRE> *
* * <PRE>
* Stack: ..., arrayref, index -&gt; ..., result.word1, result.word2
* </PRE>
*
* @version $Id: DALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DALOAD.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DALOAD extends ArrayInstruction implements StackProducer { public class DALOAD extends ArrayInstruction implements StackProducer {
/** Load double from array /**
*/ *
public DALOAD() { */
super(org.apache.bcel.Constants.DALOAD); private static final long serialVersionUID = 1L;
}
/**
* Load double from array
*/
public DALOAD() {
super(org.apache.bcel.Constants.DALOAD);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitStackProducer(this); @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitTypedInstruction(this); v.visitStackProducer(this);
v.visitArrayInstruction(this); v.visitExceptionThrower(this);
v.visitDALOAD(this); v.visitTypedInstruction(this);
} v.visitArrayInstruction(this);
v.visitDALOAD(this);
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DASTORE - Store into double array * DASTORE - Store into double array
* <PRE>Stack: ..., arrayref, index, value.word1, value.word2 -&gt; ...</PRE> *
* * <PRE>
* Stack: ..., arrayref, index, value.word1, value.word2 -&gt; ...
* </PRE>
*
* @version $Id: DASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DASTORE.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DASTORE extends ArrayInstruction implements StackConsumer { public class DASTORE extends ArrayInstruction implements StackConsumer {
/** Store double into array /**
*/ *
public DASTORE() { */
super(org.apache.bcel.Constants.DASTORE); private static final long serialVersionUID = 1L;
}
/**
* Store double into array
*/
public DASTORE() {
super(org.apache.bcel.Constants.DASTORE);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitStackConsumer(this); @Override
v.visitExceptionThrower(this); public void accept(Visitor v) {
v.visitTypedInstruction(this); v.visitStackConsumer(this);
v.visitArrayInstruction(this); v.visitExceptionThrower(this);
v.visitDASTORE(this); v.visitTypedInstruction(this);
} v.visitArrayInstruction(this);
v.visitDASTORE(this);
}
} }

View File

@ -16,40 +16,52 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DCMPG - Compare doubles: value1 > value2 * DCMPG - Compare doubles: value1 > value2
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE> *
* ..., result * <PRE>
* * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;
* </PRE>
*
* ..., result
*
* @version $Id: DCMPG.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DCMPG.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DCMPG extends Instruction implements TypedInstruction, StackProducer, StackConsumer { public class DCMPG extends Instruction implements TypedInstruction,
StackProducer, StackConsumer {
public DCMPG() { /**
super(org.apache.bcel.Constants.DCMPG, (short) 1); *
} */
private static final long serialVersionUID = 1L;
public DCMPG() {
super(org.apache.bcel.Constants.DCMPG, (short) 1);
}
/** @return Type.DOUBLE /**
*/ * @return Type.DOUBLE
public Type getType( ConstantPoolGen cp ) { */
return Type.DOUBLE; @Override
} public Type getType(ConstantPoolGen cp) {
return Type.DOUBLE;
}
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
v.visitTypedInstruction(this); public void accept(Visitor v) {
v.visitStackProducer(this); v.visitTypedInstruction(this);
v.visitStackConsumer(this); v.visitStackProducer(this);
v.visitDCMPG(this); v.visitStackConsumer(this);
} v.visitDCMPG(this);
}
} }

View File

@ -16,40 +16,52 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DCMPL - Compare doubles: value1 < value2 * DCMPL - Compare doubles: value1 < value2
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE> *
* ..., result * <PRE>
* * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;
* </PRE>
*
* ..., result
*
* @version $Id: DCMPL.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DCMPL.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DCMPL extends Instruction implements TypedInstruction, StackProducer, StackConsumer { public class DCMPL extends Instruction implements TypedInstruction,
StackProducer, StackConsumer {
public DCMPL() { /**
super(org.apache.bcel.Constants.DCMPL, (short) 1); *
} */
private static final long serialVersionUID = 1L;
public DCMPL() {
super(org.apache.bcel.Constants.DCMPL, (short) 1);
}
/** @return Type.DOUBLE /**
*/ * @return Type.DOUBLE
public Type getType( ConstantPoolGen cp ) { */
return Type.DOUBLE; @Override
} public Type getType(ConstantPoolGen cp) {
return Type.DOUBLE;
}
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
v.visitTypedInstruction(this); public void accept(Visitor v) {
v.visitStackProducer(this); v.visitTypedInstruction(this);
v.visitStackConsumer(this); v.visitStackProducer(this);
v.visitDCMPL(this); v.visitStackConsumer(this);
} v.visitDCMPL(this);
}
} }

View File

@ -16,65 +16,73 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DCONST - Push 0.0 or 1.0, other values cause an exception * DCONST - Push 0.0 or 1.0, other values cause an exception
* *
* <PRE>Stack: ... -&gt; ..., </PRE> * <PRE>
* * Stack: ... -&gt; ...,
* </PRE>
*
* @version $Id: DCONST.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DCONST.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DCONST extends Instruction implements ConstantPushInstruction, TypedInstruction { public class DCONST extends Instruction implements ConstantPushInstruction,
TypedInstruction {
private double value; /**
*
*/
private static final long serialVersionUID = 1L;
private double value;
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
DCONST() {
}
/** public DCONST(double f) {
* Empty constructor needed for the Class.newInstance() statement in super(org.apache.bcel.Constants.DCONST_0, (short) 1);
* Instruction.readInstruction(). Not to be used otherwise. if (f == 0.0) {
*/ opcode = org.apache.bcel.Constants.DCONST_0;
DCONST() { } else if (f == 1.0) {
} opcode = org.apache.bcel.Constants.DCONST_1;
} else {
throw new ClassGenException(
"DCONST can be used only for 0.0 and 1.0: " + f);
}
value = f;
}
@Override
public Number getValue() {
return new Double(value);
}
public DCONST(double f) { /**
super(org.apache.bcel.Constants.DCONST_0, (short) 1); * @return Type.DOUBLE
if (f == 0.0) { */
opcode = org.apache.bcel.Constants.DCONST_0; @Override
} else if (f == 1.0) { public Type getType(ConstantPoolGen cp) {
opcode = org.apache.bcel.Constants.DCONST_1; return Type.DOUBLE;
} else { }
throw new ClassGenException("DCONST can be used only for 0.0 and 1.0: " + f);
}
value = f;
}
/**
public Number getValue() { * Call corresponding visitor method(s). The order is: Call visitor methods
return new Double(value); * of implemented interfaces first, then call methods according to the class
} * hierarchy in descending order, i.e., the most specific visitXXX() call
* comes last.
*
/** @return Type.DOUBLE * @param v
*/ * Visitor object
public Type getType( ConstantPoolGen cp ) { */
return Type.DOUBLE; @Override
} public void accept(Visitor v) {
v.visitPushInstruction(this);
v.visitStackProducer(this);
/** v.visitTypedInstruction(this);
* Call corresponding visitor method(s). The order is: v.visitConstantPushInstruction(this);
* Call visitor methods of implemented interfaces first, then v.visitDCONST(this);
* call methods according to the class hierarchy in descending order, }
* i.e., the most specific visitXXX() call comes last.
*
* @param v Visitor object
*/
public void accept( Visitor v ) {
v.visitPushInstruction(this);
v.visitStackProducer(this);
v.visitTypedInstruction(this);
v.visitConstantPushInstruction(this);
v.visitDCONST(this);
}
} }

View File

@ -16,36 +16,47 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DDIV - Divide doubles * DDIV - Divide doubles
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE> *
* ..., result.word1, result.word2 * <PRE>
* * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;
* </PRE>
*
* ..., result.word1, result.word2
*
* @version $Id: DDIV.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DDIV.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DDIV extends ArithmeticInstruction { public class DDIV extends ArithmeticInstruction {
/** Divide doubles /**
*/ *
public DDIV() { */
super(org.apache.bcel.Constants.DDIV); private static final long serialVersionUID = 1L;
}
/**
* Divide doubles
*/
public DDIV() {
super(org.apache.bcel.Constants.DDIV);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitArithmeticInstruction(this); v.visitStackProducer(this);
v.visitDDIV(this); v.visitStackConsumer(this);
} v.visitArithmeticInstruction(this);
v.visitDDIV(this);
}
} }

View File

@ -16,42 +16,55 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DLOAD - Load double from local variable * DLOAD - Load double from local variable
* <PRE>Stack ... -&gt; ..., result.word1, result.word2</PRE> *
* * <PRE>
* Stack ... -&gt; ..., result.word1, result.word2
* </PRE>
*
* @version $Id: DLOAD.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DLOAD.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DLOAD extends LoadInstruction { public class DLOAD extends LoadInstruction {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
DLOAD() {
super(org.apache.bcel.Constants.DLOAD, org.apache.bcel.Constants.DLOAD_0);
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
DLOAD() {
super(org.apache.bcel.Constants.DLOAD,
org.apache.bcel.Constants.DLOAD_0);
}
/** Load double from local variable /**
* @param n index of local variable * Load double from local variable
*/ *
public DLOAD(int n) { * @param n
super(org.apache.bcel.Constants.DLOAD, org.apache.bcel.Constants.DLOAD_0, n); * index of local variable
} */
public DLOAD(int n) {
super(org.apache.bcel.Constants.DLOAD,
org.apache.bcel.Constants.DLOAD_0, n);
}
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
super.accept(v); public void accept(Visitor v) {
v.visitDLOAD(this); super.accept(v);
} v.visitDLOAD(this);
}
} }

View File

@ -16,36 +16,47 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DMUL - Multiply doubles * DMUL - Multiply doubles
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE> *
* ..., result.word1, result.word2 * <PRE>
* * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;
* </PRE>
*
* ..., result.word1, result.word2
*
* @version $Id: DMUL.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DMUL.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DMUL extends ArithmeticInstruction { public class DMUL extends ArithmeticInstruction {
/** Multiply doubles /**
*/ *
public DMUL() { */
super(org.apache.bcel.Constants.DMUL); private static final long serialVersionUID = 1L;
}
/**
* Multiply doubles
*/
public DMUL() {
super(org.apache.bcel.Constants.DMUL);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitArithmeticInstruction(this); v.visitStackProducer(this);
v.visitDMUL(this); v.visitStackConsumer(this);
} v.visitArithmeticInstruction(this);
v.visitDMUL(this);
}
} }

View File

@ -16,33 +16,42 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DNEG - Negate double * DNEG - Negate double
* <PRE>Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2</PRE> *
* * <PRE>
* Stack: ..., value.word1, value.word2 -&gt; ..., result.word1, result.word2
* </PRE>
*
* @version $Id: DNEG.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DNEG.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DNEG extends ArithmeticInstruction { public class DNEG extends ArithmeticInstruction {
public DNEG() { /**
super(org.apache.bcel.Constants.DNEG); *
} */
private static final long serialVersionUID = 1L;
public DNEG() {
super(org.apache.bcel.Constants.DNEG);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitArithmeticInstruction(this); v.visitStackProducer(this);
v.visitDNEG(this); v.visitStackConsumer(this);
} v.visitArithmeticInstruction(this);
v.visitDNEG(this);
}
} }

View File

@ -16,36 +16,47 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DREM - Remainder of doubles * DREM - Remainder of doubles
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE> *
* ..., result.word1, result.word2 * <PRE>
* * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;
* </PRE>
*
* ..., result.word1, result.word2
*
* @version $Id: DREM.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DREM.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DREM extends ArithmeticInstruction { public class DREM extends ArithmeticInstruction {
/** Remainder of doubles /**
*/ *
public DREM() { */
super(org.apache.bcel.Constants.DREM); private static final long serialVersionUID = 1L;
}
/**
* Remainder of doubles
*/
public DREM() {
super(org.apache.bcel.Constants.DREM);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitArithmeticInstruction(this); v.visitStackProducer(this);
v.visitDREM(this); v.visitStackConsumer(this);
} v.visitArithmeticInstruction(this);
v.visitDREM(this);
}
} }

View File

@ -16,35 +16,45 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DRETURN - Return double from method * DRETURN - Return double from method
* <PRE>Stack: ..., value.word1, value.word2 -&gt; &lt;empty&gt;</PRE> *
* * <PRE>
* Stack: ..., value.word1, value.word2 -&gt; &lt;empty&gt;
* </PRE>
*
* @version $Id: DRETURN.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DRETURN.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DRETURN extends ReturnInstruction { public class DRETURN extends ReturnInstruction {
/** Return double from method /**
*/ *
public DRETURN() { */
super(org.apache.bcel.Constants.DRETURN); private static final long serialVersionUID = 1L;
}
/**
* Return double from method
*/
public DRETURN() {
super(org.apache.bcel.Constants.DRETURN);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitExceptionThrower(this); @Override
v.visitTypedInstruction(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitExceptionThrower(this);
v.visitReturnInstruction(this); v.visitTypedInstruction(this);
v.visitDRETURN(this); v.visitStackConsumer(this);
} v.visitReturnInstruction(this);
v.visitDRETURN(this);
}
} }

View File

@ -16,42 +16,55 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DSTORE - Store double into local variable * DSTORE - Store double into local variable
* <pre>Stack: ..., value.word1, value.word2 -&gt; ... </PRE> *
* * <pre>
* Stack: ..., value.word1, value.word2 -&gt; ...
* </PRE>
*
* @version $Id: DSTORE.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DSTORE.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DSTORE extends StoreInstruction { public class DSTORE extends StoreInstruction {
/** /**
* Empty constructor needed for the Class.newInstance() statement in *
* Instruction.readInstruction(). Not to be used otherwise. */
*/ private static final long serialVersionUID = 1L;
DSTORE() {
super(org.apache.bcel.Constants.DSTORE, org.apache.bcel.Constants.DSTORE_0);
}
/**
* Empty constructor needed for the Class.newInstance() statement in
* Instruction.readInstruction(). Not to be used otherwise.
*/
DSTORE() {
super(org.apache.bcel.Constants.DSTORE,
org.apache.bcel.Constants.DSTORE_0);
}
/** Store double into local variable /**
* @param n index of local variable * Store double into local variable
*/ *
public DSTORE(int n) { * @param n
super(org.apache.bcel.Constants.DSTORE, org.apache.bcel.Constants.DSTORE_0, n); * index of local variable
} */
public DSTORE(int n) {
super(org.apache.bcel.Constants.DSTORE,
org.apache.bcel.Constants.DSTORE_0, n);
}
/**
/** * Call corresponding visitor method(s). The order is: Call visitor methods
* Call corresponding visitor method(s). The order is: * of implemented interfaces first, then call methods according to the class
* Call visitor methods of implemented interfaces first, then * hierarchy in descending order, i.e., the most specific visitXXX() call
* call methods according to the class hierarchy in descending order, * comes last.
* i.e., the most specific visitXXX() call comes last. *
* * @param v
* @param v Visitor object * Visitor object
*/ */
public void accept( Visitor v ) { @Override
super.accept(v); public void accept(Visitor v) {
v.visitDSTORE(this); super.accept(v);
} v.visitDSTORE(this);
}
} }

View File

@ -16,36 +16,47 @@
*/ */
package org.apache.bcel.generic; package org.apache.bcel.generic;
/** /**
* DSUB - Substract doubles * DSUB - Substract doubles
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;</PRE> *
* ..., result.word1, result.word2 * <PRE>
* * Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -&gt;
* </PRE>
*
* ..., result.word1, result.word2
*
* @version $Id: DSUB.java 386056 2006-03-15 11:31:56Z tcurdt $ * @version $Id: DSUB.java 386056 2006-03-15 11:31:56Z tcurdt $
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A> * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/ */
public class DSUB extends ArithmeticInstruction { public class DSUB extends ArithmeticInstruction {
/** Substract doubles /**
*/ *
public DSUB() { */
super(org.apache.bcel.Constants.DSUB); private static final long serialVersionUID = 1L;
}
/**
* Substract doubles
*/
public DSUB() {
super(org.apache.bcel.Constants.DSUB);
}
/** /**
* Call corresponding visitor method(s). The order is: * Call corresponding visitor method(s). The order is: Call visitor methods
* Call visitor methods of implemented interfaces first, then * of implemented interfaces first, then call methods according to the class
* call methods according to the class hierarchy in descending order, * hierarchy in descending order, i.e., the most specific visitXXX() call
* i.e., the most specific visitXXX() call comes last. * comes last.
* *
* @param v Visitor object * @param v
*/ * Visitor object
public void accept( Visitor v ) { */
v.visitTypedInstruction(this); @Override
v.visitStackProducer(this); public void accept(Visitor v) {
v.visitStackConsumer(this); v.visitTypedInstruction(this);
v.visitArithmeticInstruction(this); v.visitStackProducer(this);
v.visitDSUB(this); v.visitStackConsumer(this);
} v.visitArithmeticInstruction(this);
v.visitDSUB(this);
}
} }

Some files were not shown because too many files have changed in this diff Show More