Clean up apache BCEL lib, no more stupid warnings
This commit is contained in:
parent
6548caeddb
commit
4f00ab70b1
File diff suppressed because it is too large
Load Diff
@ -20,57 +20,67 @@ 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 };
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ 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
|
||||||
@ -34,228 +34,230 @@ import org.apache.bcel.util.SyntheticRepository;
|
|||||||
*/
|
*/
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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 );
|
|
||||||
}
|
}
|
||||||
|
@ -17,21 +17,24 @@
|
|||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
* The structure and the names comply, except for a few conveniences, exactly
|
||||||
* exactly with the <A href="ftp://java.sun.com/docs/specs/vmspec.ps">
|
* with the <A href="ftp://java.sun.com/docs/specs/vmspec.ps"> JVM specification
|
||||||
* JVM specification 1.0</a>. See this paper for
|
* 1.0</a>. See this paper for further details about the structure of a bytecode
|
||||||
* further details about the structure of a bytecode file.
|
* 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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,331 +22,350 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,107 +25,111 @@ 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 + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,107 +22,111 @@ 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 + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,98 +22,103 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,46 +24,54 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,99 +22,104 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,98 +22,103 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,47 +23,57 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,98 +22,103 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,46 +24,54 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,127 +22,131 @@ 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 + ")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,17 @@
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,106 +22,111 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,95 +22,100 @@ 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") + "\")";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,133 +23,146 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
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.
|
||||||
*
|
*
|
||||||
@ -28,134 +28,134 @@ package org.apache.bcel.classfile;
|
|||||||
*/
|
*/
|
||||||
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 ) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,159 +22,170 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,182 +25,186 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,192 +23,193 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -27,222 +27,230 @@ import org.apache.bcel.Constants;
|
|||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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
@ -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 );
|
|
||||||
}
|
}
|
||||||
|
@ -18,33 +18,43 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* AALOAD - Load reference from array
|
* AALOAD - Load reference from array
|
||||||
* <PRE>Stack: ..., arrayref, index -> value</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref, index -> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,44 @@
|
|||||||
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 -> ...</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref, index, value -> ...
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,40 +18,51 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ACONST_NULL - Push null reference
|
* ACONST_NULL - Push null reference
|
||||||
* <PRE>Stack: ... -> ..., null</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ... -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,40 +18,53 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ALOAD - Load reference from local variable
|
* ALOAD - Load reference from local variable
|
||||||
* <PRE>Stack: ... -> ..., objectref</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ... -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,61 +19,71 @@ 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 -> ..., arrayref</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., count -> ..., 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,35 +17,44 @@
|
|||||||
package org.apache.bcel.generic;
|
package org.apache.bcel.generic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ARETURN - Return reference from method
|
* ARETURN - Return reference from method
|
||||||
* <PRE>Stack: ..., objectref -> <empty></PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., objectref -> <empty>
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,41 +17,51 @@
|
|||||||
package org.apache.bcel.generic;
|
package org.apache.bcel.generic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ARRAYLENGTH - Get length of array
|
* ARRAYLENGTH - Get length of array
|
||||||
* <PRE>Stack: ..., arrayref -> ..., length</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,40 +18,53 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ASTORE - Store reference into local variable
|
* ASTORE - Store reference into local variable
|
||||||
* <PRE>Stack ..., objectref -> ... </PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack ..., objectref -> ...
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,42 +17,51 @@
|
|||||||
package org.apache.bcel.generic;
|
package org.apache.bcel.generic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ATHROW - Throw exception
|
* ATHROW - Throw exception
|
||||||
* <PRE>Stack: ..., objectref -> objectref</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., objectref -> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ 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 {
|
||||||
}
|
}
|
||||||
|
@ -22,73 +22,79 @@ 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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,62 +20,68 @@ 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,106 +22,113 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,33 +18,43 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* BALOAD - Load byte or boolean from array
|
* BALOAD - Load byte or boolean from array
|
||||||
* <PRE>Stack: ..., arrayref, index -> ..., value</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref, index -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,44 @@
|
|||||||
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 -> ...</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref, index, value -> ...
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,83 +23,91 @@ import org.apache.bcel.util.ByteSequence;
|
|||||||
/**
|
/**
|
||||||
* BIPUSH - Push byte on stack
|
* BIPUSH - Push byte on stack
|
||||||
*
|
*
|
||||||
* <PRE>Stack: ... -> ..., value</PRE>
|
* <PRE>
|
||||||
|
* Stack: ... -> ..., 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,24 +20,30 @@ 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,60 +22,68 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,210 +21,229 @@ 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:
|
||||||
|
*
|
||||||
|
* <position in byte code> <name of opcode> "["<opcode
|
||||||
|
* number>"]" "("<length of instruction>")" "<"<target
|
||||||
|
* instruction>">" "@"<branch target offset>
|
||||||
|
*
|
||||||
|
* @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
|
||||||
*
|
*/
|
||||||
* <position in byte code>
|
@Override
|
||||||
* <name of opcode> "["<opcode number>"]"
|
public boolean containsTarget(InstructionHandle ih) {
|
||||||
* "("<length of instruction>")"
|
return (target == ih);
|
||||||
* "<"<target instruction>">" "@"<branch target offset>
|
}
|
||||||
*
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,33 +18,43 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* CALOAD - Load char from array
|
* CALOAD - Load char from array
|
||||||
* <PRE>Stack: ..., arrayref, index -> ..., value</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref, index -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,44 @@
|
|||||||
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 -> ...</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref, index, value -> ...
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,65 +20,79 @@ import org.apache.bcel.ExceptionConstants;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* CHECKCAST - Check whether object is of given type
|
* CHECKCAST - Check whether object is of given type
|
||||||
* <PRE>Stack: ..., objectref -> ..., objectref</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., objectref -> ..., 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,115 +24,129 @@ 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) {
|
* <name of opcode> "["<opcode number>"]" "("<length of
|
||||||
super(opcode, (short) 3);
|
* instruction>")" "<"< constant pool index>">"
|
||||||
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.
|
||||||
*
|
*
|
||||||
* <name of opcode> "["<opcode number>"]"
|
* @param index
|
||||||
* "("<length of instruction>")" "<"< constant pool index>">"
|
* 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
@ -17,20 +17,24 @@
|
|||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ package org.apache.bcel.generic;
|
|||||||
* 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);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ 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
|
||||||
@ -28,157 +28,171 @@ import org.apache.bcel.classfile.CodeException;
|
|||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
* The interface provides the possibilty for the user to write `templates' or
|
||||||
* `templates' or `macros' for such reuseable code patterns.
|
* `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
@ -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
|
||||||
|
* $
|
||||||
|
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
|
||||||
*
|
*
|
||||||
* @version $Id: ConstantPushInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
|
|
||||||
* @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();
|
||||||
}
|
}
|
||||||
|
@ -22,55 +22,61 @@ 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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,33 +18,43 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* D2F - Convert double to float
|
* D2F - Convert double to float
|
||||||
* <PRE>Stack: ..., value.word1, value.word2 -> ..., result</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., value.word1, value.word2 -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,33 +18,43 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* D2I - Convert double to int
|
* D2I - Convert double to int
|
||||||
* <PRE>Stack: ..., value.word1, value.word2 -> ..., result</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., value.word1, value.word2 -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,33 +18,43 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* D2L - Convert double to long
|
* D2L - Convert double to long
|
||||||
* <PRE>Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., value.word1, value.word2 -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,34 +18,45 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DADD - Add doubles
|
* DADD - Add doubles
|
||||||
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -></PRE>
|
*
|
||||||
* ..., result.word1, result1.word2
|
* <PRE>
|
||||||
|
* Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,33 +18,43 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DALOAD - Load double from array
|
* DALOAD - Load double from array
|
||||||
* <PRE>Stack: ..., arrayref, index -> ..., result.word1, result.word2</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref, index -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,44 @@
|
|||||||
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 -> ...</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., arrayref, index, value.word1, value.word2 -> ...
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,38 +18,50 @@ 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 -></PRE>
|
*
|
||||||
* ..., result
|
* <PRE>
|
||||||
|
* Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,38 +18,50 @@ 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 -></PRE>
|
*
|
||||||
* ..., result
|
* <PRE>
|
||||||
|
* Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,62 +19,70 @@ 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: ... -> ..., </PRE>
|
* <PRE>
|
||||||
|
* Stack: ... -> ...,
|
||||||
|
* </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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,35 +17,46 @@
|
|||||||
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 -></PRE>
|
*
|
||||||
* ..., result.word1, result.word2
|
* <PRE>
|
||||||
|
* Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,40 +18,53 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DLOAD - Load double from local variable
|
* DLOAD - Load double from local variable
|
||||||
* <PRE>Stack ... -> ..., result.word1, result.word2</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack ... -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,34 +18,45 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DMUL - Multiply doubles
|
* DMUL - Multiply doubles
|
||||||
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -></PRE>
|
*
|
||||||
* ..., result.word1, result.word2
|
* <PRE>
|
||||||
|
* Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,31 +18,40 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DNEG - Negate double
|
* DNEG - Negate double
|
||||||
* <PRE>Stack: ..., value.word1, value.word2 -> ..., result.word1, result.word2</PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., value.word1, value.word2 -> ..., 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,34 +18,45 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DREM - Remainder of doubles
|
* DREM - Remainder of doubles
|
||||||
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -></PRE>
|
*
|
||||||
* ..., result.word1, result.word2
|
* <PRE>
|
||||||
|
* Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,44 @@
|
|||||||
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 -> <empty></PRE>
|
*
|
||||||
|
* <PRE>
|
||||||
|
* Stack: ..., value.word1, value.word2 -> <empty>
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,40 +18,53 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DSTORE - Store double into local variable
|
* DSTORE - Store double into local variable
|
||||||
* <pre>Stack: ..., value.word1, value.word2 -> ... </PRE>
|
*
|
||||||
|
* <pre>
|
||||||
|
* Stack: ..., value.word1, value.word2 -> ...
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,34 +18,45 @@ package org.apache.bcel.generic;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* DSUB - Substract doubles
|
* DSUB - Substract doubles
|
||||||
* <PRE>Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 -></PRE>
|
*
|
||||||
* ..., result.word1, result.word2
|
* <PRE>
|
||||||
|
* Stack: ..., value1.word1, value1.word2, value2.word1, value2.word2 ->
|
||||||
|
* </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
Loading…
Reference in New Issue
Block a user