JavaClass/ 40755 157 13 0 6613636374 11654 5 ustar dahm institut JavaClass/DE/ 40755 157 13 0 6613636074 12141 5 ustar dahm institut JavaClass/DE/fub/ 40755 157 13 0 6613636074 12715 5 ustar dahm institut JavaClass/DE/fub/inf/ 40755 157 13 0 6613636074 13471 5 ustar dahm institut JavaClass/DE/fub/inf/JVM/ 40755 157 13 0 6613636311 14117 5 ustar dahm institut JavaClass/DE/fub/inf/JVM/JavaClass/ 40755 157 13 0 6613636314 15771 5 ustar dahm institut JavaClass/DE/fub/inf/JVM/JavaClass/ConstantCP.java 100644 157 13 5012 6613635760 20747 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* Abstract super class for Fieldref and Method constants.
*
* @version $Id: ConstantCP.java,v 1.2 1998/10/22 14:06:40 dahm Exp $
* @author M. Dahm
* @see ConstantFieldref
* @see ConstantMethodref
* @see ConstantInterfaceMethodref
*/
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;
/**
* Initialize from another object.
*/
public ConstantCP(ConstantCP c) {
this(c.getTag(), c.getClassIndex(), c.getNameAndTypeIndex());
}
/**
* Initialize instance from file data.
*
* @param tag Constant type tag
* @param file Input stream
* @throw 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
*/
public 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;
}
/**
* Dump constant field reference to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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 belongs to.
*/
public final int getClassIndex() { return class_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;
}
/**
* @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 + ")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Method.java 100644 157 13 16256 6565066071 20206 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents the method info structure, i.e. the representation
* for a method in the class. See JVM specification for details.
* A method has access flags, a name, a signature and a number of attributes.
*
* @version $Id: Method.java,v 1.3 1998/08/14 16:56:25 dahm Exp $
* @author M. Dahm
*/
public final class Method implements Constants, Cloneable {
private int access_flags; // Access rights of field
private int name_index; // Points to field name in constant pool
private int signature_index; // Points to encoded signature
private int attributes_count;// No. of attributes
private Attribute[] attributes; // Collection of attributes
private ConstantPool constant_pool;
/**
* Empty constructor, all attributes have to be defined via `setXXX'
* 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) {
this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(),
c.getAttributes(), c.getConstantPool());
}
/**
* Construct object from file stream.
* @param file Input stream
* @throw IOException
* @throw ClassFormatError
*/
Method(DataInputStream file, ConstantPool constant_pool)
throws IOException, ClassFormatError
{
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++) // Implicit recursion
attributes[i] = Attribute.readAttribute(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)
{
this.access_flags = access_flags;
this.name_index = name_index;
this.signature_index = signature_index;
this.constant_pool = constant_pool;
setAttributes(attributes);
}
/**
* 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.visitMethod(this);
}
/**
* Dump method to file stream on binary format.
*
* @param file Output file stream
* @throw 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);
}
/**
* @return Access flags of the class field.
*/
public final int getAccessFlags() { return access_flags; }
/**
* @return Collection of method attributes.
*/
public final Attribute[] getAttributes() { return attributes; }
/**
* @return Code attribute of method, if any
*/
public final Code getCode() {
for(int i=0; i < attributes.length; i++)
if(attributes[i] instanceof Code)
return (Code)attributes[i];
return null;
}
/**
* @return ExceptionTable attribute of method, if any
*/
public final ExceptionTable getExceptionTable() {
for(int i=0; i < attributes.length; i++)
if(attributes[i] instanceof ExceptionTable)
return (ExceptionTable)attributes[i];
return null;
}
/**
* @return Constant pool used by this object.
* @see ConstantPool
*/
public final ConstantPool getConstantPool() { return constant_pool; }
/**
* @return Name of method
*/
public final String getName() {
ConstantUtf8 c;
c = (ConstantUtf8)constant_pool.getConstant(name_index,
CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return Index in constant pool of field name.
*/
public final int getNameIndex() { return name_index; }
/**
* @return String representation of method type signature.
*/
public final String getSignature() {
ConstantUtf8 c;
c = (ConstantUtf8)constant_pool.getConstant(signature_index,
CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return Index in constant pool of field signature.
*/
public final int getSignatureIndex() { return signature_index; }
/**
* @param access_flags.
*/
public final void setAccessFlags(int access_flags) {
this.access_flags = access_flags;
}
/**
* @param attributes.
*/
public final void setAttributes(Attribute[] attributes) {
this.attributes = attributes;
attributes_count = (attributes == null)? 0 : attributes.length;
}
/**
* @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;
}
/**
* @param name_index.
*/
public final void setNameIndex(int name_index) {
this.name_index = name_index;
}
/**
* @param signature_index.
*/
public final void setSignatureIndex(int signature_index) {
this.signature_index = signature_index;
}
/**
* Return string representation close to declaration format,
* `public static int main(String[]) throws IOException', e.g.
*
* @return String representation of the method.
*/
public final String toString()
{
ConstantUtf8 c;
ConstantValue cv;
String name, signature, access; // Short cuts to constant pool
String exceptions;
StringBuffer buf;
Attribute[] attr;
access = Utility.accessToString(access_flags);
// Get name and signature from constant pool
c = (ConstantUtf8)constant_pool.getConstant(signature_index,
CONSTANT_Utf8);
signature = c.getBytes();
c = (ConstantUtf8)constant_pool.getConstant(name_index, CONSTANT_Utf8);
name = c.getBytes();
signature = Utility.methodSignatureToString(signature, name, access);
buf = new StringBuffer(signature);
ExceptionTable e = getExceptionTable();
if(e != null) {
String str = e.toString();
if(!str.equals(""))
buf.append("\n\t\tthrows " + str);
}
return buf.toString();
}
/**
* @return deep copy of this method
*/
public Method copy(ConstantPool constant_pool) {
Method c = null;
try {
c = (Method)clone();
} catch(CloneNotSupportedException e) {}
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;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Deprecated.java 100644 157 13 6001 6546432320 20762 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and denotes that this is a
* deprecated method.
* It is instantiated from the Attribute.readAttribute() method.
*
* @version $Id: Deprecated.java,v 1.1 1998/07/01 13:08:32 dahm Exp $
* @author M. Dahm
* @see Attribute
*/
public final class Deprecated extends Attribute {
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());
}
/**
* @param name_index Index in constant pool to CONSTANT_Utf8
* @param length Content length in bytes
* @param bytes Attribute contents
* @param constant_pool Array of constants
* @param sourcefile_index Index in constant pool to CONSTANT_Utf8
*/
public Deprecated(int name_index, int length, byte[] bytes,
ConstantPool constant_pool)
{
super(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
* @throw 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");
}
}
/**
* 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.visitDeprecated(this);
}
/**
* Dump source file attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
super.dump(file);
if(length > 0)
file.write(bytes, 0, length);
}
/**
* @return data bytes.
*/
public final byte[] getBytes() { return bytes; }
/**
* @param bytes.
*/
public final void setBytes(byte[] bytes) {
this.bytes = bytes;
}
/**
* @return attribute name
*/
public final String toString() {
return ATTRIBUTE_NAMES[ATTR_DEPRECATED];
}
/**
* @return deep copy of this attribute
*/
public Attribute copy(ConstantPool constant_pool) {
Deprecated c = (Deprecated)clone();
if(bytes != null)
c.bytes = (byte[])bytes.clone();
c.constant_pool = constant_pool;
return c;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantValue.java 100644 157 13 7411 6546432317 21524 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and represents a constant
* value, i.e. a default value for initializing a class field.
* This class is instantiated by the Attribute.readAttribute() method.
*
* @version $Id: ConstantValue.java,v 1.1 1998/07/01 13:08:31 dahm Exp $
* @author M. Dahm
* @see Attribute
*/
public final class ConstantValue extends Attribute {
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());
}
/**
* Construct object from file stream.
* @param name_index Name index in constant pool
* @param length Content length in bytes
* @param file Input stream
* @param constant_pool Array of constants
* @throw IOException
*/
ConstantValue(int name_index, int length, DataInputStream file,
ConstantPool constant_pool) throws IOException
{
this(name_index, length, (int)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(ATTR_CONSTANT_VALUE, name_index, length, constant_pool);
this.constantvalue_index = constantvalue_index;
}
/**
* 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.visitConstantValue(this);
}
/**
* Dump constant value attribute to file stream on binary format.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
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.
*/
public final void setConstantValueIndex(int constantvalue_index) {
this.constantvalue_index = constantvalue_index;
}
/**
* @return String representation of constant value.
*/
public final String toString() throws InternalError
{
Constant c = constant_pool.getConstant(constantvalue_index);
String buf;
int i;
// Print constant to string depending on its type
switch(c.getTag()) {
case CONSTANT_Long: buf = "" + ((ConstantLong)c).getBytes(); break;
case CONSTANT_Float: buf = "" + ((ConstantFloat)c).getBytes(); break;
case CONSTANT_Double: buf = "" + ((ConstantDouble)c).getBytes(); break;
case CONSTANT_Integer: buf = "" + ((ConstantInteger)c).getBytes(); break;
case CONSTANT_String:
i = ((ConstantString)c).getStringIndex();
c = constant_pool.getConstant(i, CONSTANT_Utf8);
buf = "\"" + ((ConstantUtf8)c).getBytes() + "\"";
break;
default: throw new InternalError("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;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/SourceFile.java 100644 157 13 6116 6546432334 20776 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and represents a reference
* to the source file of this class.
* It is instantiated from the Attribute.readAttribute() method.
*
* @version $Id: SourceFile.java,v 1.1 1998/07/01 13:08:44 dahm Exp $
* @author M. Dahm
* @see Attribute
*/
public final class SourceFile extends Attribute {
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());
}
/**
* 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
* @throw 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
* @param length Content length in bytes
* @param constant_pool Array of constants
* @param sourcefile_index Index in constant pool to CONSTANT_Utf8
*/
public SourceFile(int name_index, int length, int sourcefile_index,
ConstantPool constant_pool)
{
super(ATTR_SOURCE_FILE, name_index, length, constant_pool);
this.sourcefile_index = sourcefile_index;
}
/**
* 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.visitSourceFile(this);
}
/**
* Dump source file attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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,
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();
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantUtf8.java 100644 157 13 5210 6546432316 21270 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to a Utf8 encoded string.
*
* @version $Id: ConstantUtf8.java,v 1.1 1998/07/01 13:08:30 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantUtf8 extends Constant {
private int length; // Length of string.
/* This does not follow the specification closely, but is much more
* convenient. Could rather be of type `byte[]'.
*/
private String bytes;
/**
* Initialize from another object.
*/
public ConstantUtf8(ConstantUtf8 c) {
this(c.getBytes());
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantUtf8(DataInputStream file) throws IOException
{
super(CONSTANT_Utf8);
length = file.readUnsignedShort();
byte[] bytes = new byte[length];
file.readFully(bytes); // Block until all is being read
// this.bytes = new String(bytes, 0); // deprecated
this.bytes = new String(bytes);
}
/**
* @param bytes Data
*/
public ConstantUtf8(String bytes)
{
super(CONSTANT_Utf8);
this.bytes = bytes;
this.length = (bytes == null)? 0 : bytes.length();
}
/**
* 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.visitConstantUtf8(this);
}
/**
* Dump String in Utf8 format to file stream.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
file.writeByte(tag);
file.writeShort(length);
file.writeBytes(bytes);
}
/**
* @return Data converted to string.
*/
public final String getBytes() { return bytes; }
/**
* @return String length.
*/
public final int getLength() { return length; }
/**
* @param bytes.
*/
public final void setBytes(String bytes) {
this.bytes = bytes;
}
/**
* @param length.
*/
public final void setLength(int length) {
this.length = length;
}
/**
* @return String representation
*/
public final String toString()
{
return super.toString() + "(length = " + length +
", bytes = \"" + Utility.replace(bytes, "\n", "\\n") + "\")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantMethodref.java 100644 157 13 2557 6613136461 22367 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents a constant pool reference to a method.
*
* @version $Id: ConstantMethodref.java,v 1.1 1998/07/01 13:08:25 dahm Exp $
* @author M. Dahm
*/
public final class ConstantMethodref extends ConstantCP {
/**
* Initialize from another object.
*/
public ConstantMethodref(ConstantMethodref c) {
super(CONSTANT_Methodref, c.getClassIndex(), c.getNameAndTypeIndex());
}
/**
* Initialize instance from file data.
*
* @param file input stream
* @throw IOException
*/
ConstantMethodref(DataInputStream file) throws IOException
{
super(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(CONSTANT_Methodref, class_index, name_and_type_index);
}
/**
* 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.visitConstantMethodref(this);
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/PMGClass.java 100644 157 13 7136 6546432333 20351 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and represents a reference
* to a PMG attribute.
*
* @version $Id: PMGClass.java,v 1.1 1998/07/01 13:08:43 dahm Exp $
* @author M. Dahm
* @see Attribute
*/
public final class PMGClass extends Attribute {
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());
}
/**
* 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
* @throw 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 constant_pool Array of constants
* @param PMGClass_index Index in constant pool to CONSTANT_Utf8
*/
public PMGClass(int name_index, int length, int pmg_index, int pmg_class_index,
ConstantPool constant_pool)
{
super(ATTR_PMG, name_index, length, constant_pool);
this.pmg_index = pmg_index;
this.pmg_class_index = pmg_class_index;
}
/**
* 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) {
System.err.println("Visiting non-standard PMGClass object");
}
/**
* Dump source file attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
super.dump(file);
file.writeShort(pmg_index);
file.writeShort(pmg_class_index);
}
/**
* @return Index in constant pool of source file name.
*/
public final int getPMGClassIndex() { return pmg_class_index; }
/**
* @param PMGClass_index.
*/
public final void setPMGClassIndex(int pmg_class_index) {
this.pmg_class_index = pmg_class_index;
}
/**
* @return Index in constant pool of source file name.
*/
public final int getPMGIndex() { return pmg_index; }
/**
* @param PMGClass_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,
CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return PMG class name.
*/
public final String getPMGClassName() {
ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(pmg_class_index,
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();
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantFloat.java 100644 157 13 3761 6546432305 21516 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to a float object.
*
* @version $Id: ConstantFloat.java,v 1.1 1998/07/01 13:08:21 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantFloat extends Constant {
private float bytes;
/**
* @param bytes Data
*/
public ConstantFloat(float bytes)
{
super(CONSTANT_Float);
this.bytes = bytes;
}
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public ConstantFloat(ConstantFloat c) {
this(c.getBytes());
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantFloat(DataInputStream file) throws IOException
{
this(file.readFloat());
}
/**
* 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.visitConstantFloat(this);
}
/**
* Dump constant float to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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.
*/
public final void setBytes(float bytes) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Field.java 100644 157 13 14471 6611373006 17775 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents the field info structure, i.e. the representation
* for a variable in the class. See JVM specification for details.
*
* @version $Id: Field.java,v 1.3 1998/10/15 13:17:58 dahm Exp $
* @author M. Dahm
*/
public final class Field implements Constants, Cloneable {
private int access_flags; // Access rights of field
private int name_index; // Points to field name in constant pool
private int signature_index; // Points to encoded signature
private int attributes_count;// No. of attributes
private Attribute[] attributes; // Collection of attributes
private ConstantPool constant_pool;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public Field(Field c) {
this(c.getAccessFlags(), c.getNameIndex(), c.getSignatureIndex(),
c.getAttributes(), c.getConstantPool());
}
/**
* Construct object from file stream.
* @param file Input stream
*/
Field(DataInputStream file, ConstantPool constant_pool)
throws IOException, ClassFormatError
{
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 access_flags Access rights of field
* @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 Field(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);
}
/**
* 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.visitField(this);
}
/**
* Dump field to file stream on binary format.
*
* @param file Output file stream
* @throw 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);
}
/**
* @return Access flags of the class field.
*/
public final int getAccessFlags() { return access_flags; }
/**
* @return Collection of field attributes.
*/
public final Attribute[] getAttributes() { return attributes; }
/**
* @return Constant pool used by this object.
* @see ConstantPool
*/
public final ConstantPool getConstantPool() { return constant_pool; }
/**
* @return Name of field
*/
public final String getName()
{
ConstantUtf8 c;
c = (ConstantUtf8)constant_pool.getConstant(name_index,
CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return Index in constant pool of field name.
*/
public final int getNameIndex() { return name_index; }
/**
* @return String representation of field type signature (java style)
*/
public final String getSignature()
{
ConstantUtf8 c;
c = (ConstantUtf8)constant_pool.getConstant(signature_index,
CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return Index in constant pool of field signature.
*/
public final int getSignatureIndex() { return signature_index; }
/**
* @param access_flags.
*/
public final void setAccessFlags(int access_flags) {
this.access_flags = access_flags;
}
/**
* @param attributes.
*/
public final void setAttributes(Attribute[] attributes) {
this.attributes = attributes;
attributes_count = (attributes == null)? 0 : attributes.length;
}
/**
* @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;
}
/**
* @param name_index.
*/
public final void setNameIndex(int name_index) {
this.name_index = name_index;
}
/**
* @param signature_index.
*/
public final void setSignatureIndex(int signature_index) {
this.signature_index = signature_index;
}
/**
* @return constant value associated with this field (may be null)
*/
public final ConstantValue getConstantValue() {
for(int i=0; i < attributes_count; i++)
if(attributes[i].getTag() == ATTR_CONSTANT_VALUE)
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.
*/
public final String toString() {
String name, signature, access; // Short cuts to constant pool
String str;
// Get names from constant pool
access = Utility.accessToString(access_flags);
signature = Utility.signatureToString(getSignature());
name = getName();
str = access + " " + signature + " " + name;
ConstantValue cv = getConstantValue();
if(cv != null)
return str + " = " + cv;
else
return str.trim();
}
/**
* @return deep copy of this field
*/
public Field copy(ConstantPool constant_pool) {
Field c = null;
try {
c = (Field)clone();
} catch(CloneNotSupportedException e) {}
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;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Unknown.java 100644 157 13 7673 6550432374 20405 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
import java.util.*;
/**
* This class is derived from Attribute and represents a reference to an
* unknown (i.e. unimplemented) attribute of this class.
* It is instantiated from the Attribute.readAttribute() method.
*
* @version $Id: Unknown.java,v 1.3 1998/07/07 14:47:24 dahm Exp $
* @author M. Dahm
* @see Attribute
*/
public final class Unknown extends Attribute {
private byte[] bytes;
private String name;
private static Hashtable unknown_attributes = new Hashtable();
/** @return array of unknown attributes, but just one for each kind.
*/
static Unknown[] getUnknownAttributes() {
Unknown[] unknowns = new Unknown[unknown_attributes.size()];
Enumeration entries = unknown_attributes.elements();
for(int i=0; entries.hasMoreElements(); i++)
unknowns[i] = (Unknown)entries.nextElement();
unknown_attributes = new Hashtable();
return unknowns;
}
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public Unknown(Unknown c) {
this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
}
/**
* 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(ATTR_UNKNOWN, name_index, length, constant_pool);
this.bytes = bytes;
name = ((ConstantUtf8)constant_pool.getConstant(name_index,
CONSTANT_Utf8)).getBytes();
unknown_attributes.put(name, this);
}
/**
* 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
* @throw 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
*/
public void accept(Visitor v) {
v.visitUnknown(this);
}
/**
* Dump unknown bytes to file stream.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
super.dump(file);
if(length > 0)
file.write(bytes, 0, length);
}
/**
* @return data bytes.
*/
public final byte[] getBytes() { return bytes; }
/**
* @return name of attribute.
*/
public final String getName() { return name; }
/**
* @param bytes.
*/
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 = (byte[])bytes.clone();
c.constant_pool = constant_pool;
return c;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Code.java 100644 157 13 20456 6565771135 17641 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and represents a
* code chunk. It is instantiated by the
* Attribute.readAttribute() method. A Code
* attribute contains informations about operand stack, local variables,
* byte code and the exceptions handled within this method.
*
* This attribute has attributes itself, namely LineNumberTable which
* is used for debugging purposes and LocalVariableTable which
* contains information about the local variables.
*
* @version $Id: Code.java,v 1.3 1998/08/17 09:05:33 dahm Exp $
* @author M. Dahm
* @see Attribute
* @see CodeException
* @see LineNumberTable
* @see LocalVariableTable
*/
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 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 clone() 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());
}
/**
* @param name_index Index pointing to the name Code
* @param length Content length in bytes
* @param file 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);
}
/**
* @param name_index Index pointing to the name Code
* @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(ATTR_CODE, name_index, length, constant_pool);
this.max_stack = max_stack;
this.max_locals = max_locals;
setCode(code);
setExceptionTable(exception_table);
setAttributes(attributes);
}
/**
* 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.visitCode(this);
}
/**
* Dump code attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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 Collection of code attributes.
* @see Attribute
*/
public final Attribute[] getAttributes() { return attributes; }
/**
* @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;
}
/**
* @return LocalVariableTable of Code, if it has one
*/
public LocalVariableTable getLocalVariableTable() {
for(int i=0; i < attributes_count; i++)
if(attributes[i] instanceof LocalVariableTable)
return (LocalVariableTable)attributes[i];
return null;
}
/**
* @return Actual byte code of the method.
*/
public final byte[] getCode() { return code; }
/**
* @return Table of handled exceptions.
* @see CodeException
*/
public final CodeException[] getExceptionTable() { return exception_table; }
/**
* @return Number of local variables.
*/
public final int getMaxLocals() { return max_locals; }
/**
* @return Maximum size of stack used by this method.
*/
public final int getMaxStack() { return max_stack; }
/**
* @param attributes.
*/
public final void setAttributes(Attribute[] attributes) {
this.attributes = attributes;
attributes_count = (attributes == null)? 0 : attributes.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() {
StringBuffer buf;
buf = new StringBuffer("Code(max_stack = " + max_stack +
", max_locals = " + max_locals +
", code_length = " + code_length +
", code = \n" +
Utility.codeToString(code, constant_pool,
0, -1) + '\n');
if(exception_table_length > 0) {
buf.append(", exception_table = \n");
for(int i=0; i < exception_table_length; i++)
buf.append(exception_table[i].toString() + "\n");
}
if(attributes_count > 0) {
buf.append(", " + attributes_count + " attributes = \n");
for(int i=0; i < attributes_count; i++)
buf.append(attributes[i].toString() + "\n");
}
buf.append(")");
return buf.toString();
}
/**
* @return deep copy of this attribute
*/
public Attribute copy(ConstantPool constant_pool) {
Code c = (Code)clone();
c.code = (byte[])code.clone();
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;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantFieldref.java 100644 157 13 2541 6546432304 22163 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents a constant pool reference to a field.
*
* @version $Id: ConstantFieldref.java,v 1.1 1998/07/01 13:08:20 dahm Exp $
* @author M. Dahm
*/
public final class ConstantFieldref extends ConstantCP {
/**
* Initialize from another object.
*/
public ConstantFieldref(ConstantFieldref c) {
super(CONSTANT_Fieldref, c.getClassIndex(), c.getNameAndTypeIndex());
}
/**
* Initialize instance from file data.
*
* @param file input stream
* @throw IOException
*/
ConstantFieldref(DataInputStream file) throws IOException
{
super(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(CONSTANT_Fieldref, class_index, name_and_type_index);
}
/**
* 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 Fields,
* fields, attributes, etc. spawns a tree of objects.
*
* @param v Visitor object
*/
public void accept(Visitor v) {
v.visitConstantFieldref(this);
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/CodeException.java 100644 157 13 10362 6562073234 21503 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents an entry in the exception table of the Code
* attribute and is used only there. It contains a range in which a
* particular exception handler is active.
*
* @version $Id: CodeException.java,v 1.2 1998/08/05 15:13:32 dahm Exp $
* @author M. Dahm
* @see Code
*/
public final class CodeException implements Cloneable, Constants {
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 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());
}
/**
* Construct object from file stream.
* @param file Input stream
* @throw 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;
}
/**
* 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.visitCodeException(this);
}
/**
* Dump code exception to file stream in binary format.
*
* @param file Output file stream
* @throw 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);
}
/**
* @return 0, if the handler catches any exception, otherwise it points to
* the exception class which is to be caught.
*/
public final int getCatchType() { return catch_type; }
/**
* @return Exclusive end index of the region where the handler is active.
*/
public final int getEndPC() { return end_pc; }
/**
* @return Starting address of exception handler, relative to the code.
*/
public final int getHandlerPC() { return handler_pc; }
/**
* @return Inclusive start index of the region where the handler is active.
*/
public final int getStartPC() { return start_pc; }
/**
* @param catch_type.
*/
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 deep copy of this object
*/
public CodeException copy() {
try {
return (CodeException)clone();
} catch(CloneNotSupportedException e) {}
return null;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/InnerClass.java 100644 157 13 12061 6611373006 21004 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents a inner class attribute, i.e. the class
* indices of the inner and outer classes, the name and the attributes
* of the inner class.
*
* @version $Id: InnerClass.java,v 1.3 1998/10/15 13:17:58 dahm Exp $
* @author M. Dahm
* @see InnerClasses
*/
public final class InnerClass implements Constants, Cloneable
{
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());
}
/**
* Construct object from file stream.
* @param file Input stream
* @throw 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;
}
/**
* 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.visitInnerClass(this);
}
/**
* Dump inner class attribute to file stream in binary format.
*
* @param file Output file stream
* @throw 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);
}
/**
* @return access flags of inner class.
*/
public final int getInnerAccessFlags() { return inner_access_flags; }
/**
* @return class index of inner class.
*/
public final int getInnerClassIndex() { return inner_class_index; }
/**
* @return name index of inner class.
*/
public final int getInnerNameIndex() { return inner_name_index; }
/**
* @return class index of outer class.
*/
public final int getOuterClassIndex() { return outer_class_index; }
/**
* @param inner_access_flags.
*/
public final void setInnerAccessFlags(int inner_access_flags) {
this.inner_access_flags = inner_access_flags;
}
/**
* @param inner_class_index.
*/
public final void setInnerClassIndex(int inner_class_index) {
this.inner_class_index = inner_class_index;
}
/**
* @param inner_name_index.
*/
public final void setInnerNameIndex(int inner_name_index) {
this.inner_name_index = inner_name_index;
}
/**
* @param outer_class_index.
*/
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,
CONSTANT_Class);
inner_class_name = Utility.compactClassName(inner_class_name);
if (outer_class_index != 0) {
outer_class_name = constant_pool.getConstantString(outer_class_index,
CONSTANT_Class);
outer_class_name = Utility.compactClassName(outer_class_name);
}
else
outer_class_name = "";
if(inner_name_index != 0)
inner_name = ((ConstantUtf8)constant_pool.getConstant(inner_name_index,
CONSTANT_Utf8)).getBytes();
else
inner_name = "";
access = Utility.accessToString(inner_access_flags, true);
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;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantUnicode.java 100644 157 13 5156 6546432315 22040 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to a Unicode encoded string.
*
* @version $Id: ConstantUnicode.java,v 1.1 1998/07/01 13:08:29 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantUnicode extends Constant {
private int length; // Length of string.
/* This does not follow the specification closely, but is much more
* convenient. Could rather be of type `byte[]'.
*/
private String bytes;
/**
* Initialize from another object.
*/
public ConstantUnicode(ConstantUnicode c) {
this(c.getBytes());
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantUnicode(DataInputStream file) throws IOException
{
super(CONSTANT_Unicode);
length = file.readUnsignedShort();
char[] chbytes = new char[length];
for(int i=0; i < length; i++)
chbytes[i] = file.readChar();
bytes = new String(chbytes);
}
/**
* @param bytes Data
*/
public ConstantUnicode(String bytes)
{
super(CONSTANT_Unicode);
this.bytes = bytes;
this.length = (bytes == null)? 0 : (bytes.length() * 2); // sizeof(char) is 2
}
/**
* 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.visitConstantUnicode(this);
}
/**
* Dump String in Unicode format to file stream.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
file.writeByte(tag);
file.writeShort(length);
file.writeChars(bytes);
}
/**
* @return Data converted into normal String.
*/
public final String getBytes() { return bytes; }
/**
* @return String length.
*/
public final int getLength() { return length; }
/**
* @param bytes.
*/
public final void setBytes(String bytes) {
this.bytes = bytes;
}
/**
* @param length.
*/
public final void setLength(int length) {
this.length = length;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(length = " + length +
", bytes = \"" + bytes + "\")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantPool.java 100644 157 13 20304 6565066066 21402 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents the constant pool, i.e. a table of constants.
* It may contain null references, due to the JVM specification that skips
* an entry after an 8-byte constant (double, long) entry.
*
* @version $Id: ConstantPool.java,v 1.3 1998/08/14 16:56:22 dahm Exp $
* @see Constant
* @author M. Dahm
*/
public final class ConstantPool implements Constants, Cloneable {
private int constant_pool_count;
private Constant[] constant_pool;
/**
* @param constant_pool Array of constants
*/
public ConstantPool(Constant[] constant_pool)
{
setConstantPool(constant_pool);
}
/**
* Read constants from given file stream.
*
* @param file Input stream
* @throw IOException
* @throw ClassFormatError
*/
ConstantPool(DataInputStream file) throws IOException, ClassFormatError
{
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 == CONSTANT_Double) || (tag == 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
*/
public void accept(Visitor v) {
v.visitConstantPool(this);
}
/**
* Resolve constant to a string representation.
*
* @param constant Constant to be printed
* @return String representation
*/
public String constantToString(Constant c)
throws ClassFormatError
{
String str;
int i;
byte tag = c.getTag();
switch(tag) {
case CONSTANT_Class:
i = ((ConstantClass)c).getNameIndex();
c = getConstant(i, CONSTANT_Utf8);
str = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false);
break;
case CONSTANT_String:
i = ((ConstantString)c).getStringIndex();
c = getConstant(i, CONSTANT_Utf8);
str = "\"" + ((ConstantUtf8)c).getBytes() + "\"";
break;
case CONSTANT_Utf8: str = ((ConstantUtf8)c).getBytes(); break;
case CONSTANT_Unicode: str = ((ConstantUnicode)c).getBytes(); break;
case CONSTANT_Double: str = "" + ((ConstantDouble)c).getBytes(); break;
case CONSTANT_Float: str = "" + ((ConstantFloat)c).getBytes(); break;
case CONSTANT_Long: str = "" + ((ConstantLong)c).getBytes(); break;
case CONSTANT_Integer: str = "" + ((ConstantInteger)c).getBytes(); break;
case CONSTANT_NameAndType:
str = (constantToString(((ConstantNameAndType)c).getNameIndex(),
CONSTANT_Utf8) + " " +
constantToString(((ConstantNameAndType)c).getSignatureIndex(),
CONSTANT_Utf8));
break;
case CONSTANT_InterfaceMethodref: case CONSTANT_Methodref: case CONSTANT_Fieldref:
str = (constantToString(((ConstantCP)c).getClassIndex(),
CONSTANT_Class) + "." +
constantToString(((ConstantCP)c).getNameAndTypeIndex(),
CONSTANT_NameAndType));
break;
default: // Never reached
str = "";
}
return str;
}
/**
* Retrieve constant at `index' from constant pool and resolve it to
* a string representation.
*
* @param index of constant in constant pool
* @param tag expected type
* @return String representation
*/
public String constantToString(int index, byte tag)
throws ClassFormatError
{
Constant c = getConstant(index, tag);
return constantToString(c);
}
/**
* Dump constant pool to file stream in binary format.
*
* @param file Output file stream
* @throw 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);
}
/**
* Get constant from constant pool.
*
* @param index Index in constant pool
* @return Constant value
* @see Constant
*/
public final Constant getConstant(int index)
{
return constant_pool[index];
}
/**
* 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
* @throw ClassFormatError
*/
public final Constant getConstant(int index, byte tag)
throws ClassFormatError
{
Constant c;
c = constant_pool[index];
if(c == null)
throw new ClassFormatError("Constant pool at index " + index + " is null.");
if(c.getTag() == tag)
return c;
else
throw new ClassFormatError("Expected class `" + CONSTANT_NAMES[tag] +
"' at index " + index + " and got " + c);
}
/**
* @return Array of constants.
* @see Constant
*/
public final 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
* @throw ClassFormatError
*/
public final String getConstantString(int index, byte tag)
throws ClassFormatError
{
Constant c;
int i;
String s;
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 CONSTANT_Class: i = ((ConstantClass)c).getNameIndex(); break;
case CONSTANT_String: i = ((ConstantString)c).getStringIndex(); break;
default: throw new InternalError("getConstantString" +
"called with illegal tag " +
tag);
}
// Finally get the string from the constant pool
c = getConstant(i, CONSTANT_Utf8);
return ((ConstantUtf8)c).getBytes();
}
/**
* @return Length of constant pool.
*/
public final int getLength()
{
return constant_pool_count;
}
/**
* @param constant Constant to set
*/
public final void setConstant(int index, Constant constant) {
constant_pool[index] = constant;
}
/**
* @param constant_pool
*/
public final void setConstantPool(Constant[] constant_pool) {
this.constant_pool = constant_pool;
constant_pool_count = (constant_pool == null)? 0 : constant_pool.length;
}
/**
* @return String representation.
*/
public final String toString() {
StringBuffer buf = new StringBuffer();
for(int i=1; i < constant_pool_count; i++)
buf.append(i + ")" + constant_pool[i] + "\n");
return buf.toString();
}
/**
* @return deep copy of this constant pool
*/
public ConstantPool copy() {
ConstantPool c = null;
try {
c = (ConstantPool)clone();
} catch(CloneNotSupportedException e) {}
c.constant_pool = new Constant[constant_pool_count];
for(int i=1; i < constant_pool_count; i++)
c.constant_pool[i] = constant_pool[i].copy();
return c;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantClass.java 100644 157 13 4070 6557676370 21526 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to a (external) class.
*
* @version $Id: ConstantClass.java,v 1.2 1998/07/29 19:50:16 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantClass extends Constant
{
private int name_index; // Identical to ConstantString except for the name
/**
* Initialize from another object.
*/
public ConstantClass(ConstantClass c) {
this(c.getNameIndex());
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantClass(DataInputStream file) throws IOException
{
this(file.readUnsignedShort());
}
/**
* @param name_index Name index in constant pool
*/
public ConstantClass(int name_index) {
super(CONSTANT_Class);
this.name_index = name_index;
}
/**
* 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.visitConstantClass(this);
}
/**
* Dump constant class to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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.
*/
public final void setNameIndex(int name_index) {
this.name_index = name_index;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(name_index = " + name_index + ")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/LineNumber.java 100644 157 13 5162 6562073237 20777 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* 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
* is used for debugging purposes.
*
* @version $Id: LineNumber.java,v 1.2 1998/08/05 15:13:35 dahm Exp $
* @author M. Dahm
* @see LineNumberTable
*/
public final class LineNumber implements Cloneable {
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());
}
/**
* Construct object from file stream.
* @param file Input stream
* @throw 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;
}
/**
* 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.visitLineNumber(this);
}
/**
* Dump line number/pc pair to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
file.writeShort(start_pc);
file.writeShort(line_number);
}
/**
* @return Corresponding source line
*/
public final int getLineNumber() { return line_number; }
/**
* @return PC in code
*/
public final int getStartPC() { return start_pc; }
/**
* @param line_number.
*/
public final void setLineNumber(int line_number) {
this.line_number = line_number;
}
/**
* @param start_pc.
*/
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;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/InnerClasses.java 100644 157 13 7324 6546432324 21330 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and denotes that this class
* is an Inner class of another.
* to the source file of this class.
* It is instantiated from the Attribute.readAttribute() method.
*
* @version $Id: InnerClasses.java,v 1.1 1998/07/01 13:08:36 dahm Exp $
* @author M. Dahm
* @see Attribute
*/
public final class InnerClasses extends Attribute {
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());
}
/**
* @param name_index Index in constant pool to CONSTANT_Utf8
* @param length Content length in bytes
* @param inner_classes array of inner classes attributes
* @param constant_pool Array of constants
* @param sourcefile_index Index in constant pool to CONSTANT_Utf8
*/
public InnerClasses(int name_index, int length,
InnerClass[] inner_classes,
ConstantPool constant_pool)
{
super(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
* @throw 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);
}
/**
* 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.visitInnerClasses(this);
}
/**
* Dump source file attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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);
}
/**
* @return Index in constant pool of source file name.
*/
public final InnerClass[] getInnerClasses() { return inner_classes; }
/**
* @param 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) + "\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;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/GNUmakefile 100644 157 13 33 6365604630 20074 0 ustar dahm institut include ../Makefile.common
JavaClass/DE/fub/inf/JVM/JavaClass/Utility.java 100644 157 13 72367 6612665043 20433 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import DE.fub.inf.JVM.Util.ByteSequence;
import java.io.*;
import java.util.Vector;
/**
* Utility functions that do not really belong to any class in particular.
*
* @version $Id: Utility.java,v 1.9 1998/10/19 16:34:43 dahm Exp $
* @author M. Dahm
*/
public abstract class Utility implements Constants {
private static int consumed_chars; /* How many chars have been consumed
* during parsing in signatureToString().
* Read by methodSignatureToString().
* Set by side effect,but only internally.
*/
private static boolean wide=false; /* The `WIDE' instruction is used in the
* byte code to allow 16-bit wide indices
* for local variables. This opcode
* precedes an `ILOAD', e.g.. The opcode
* immediately following takes an extra
* byte which is combined with the
* following byte to form a
* 16-bit value.
*/
/**
* Convert bit field of flags into string such as `static final'.
*
* @param access_flags Access flags
* @return String representation of flags
*/
public static final String accessToString(int access_flags)
{
return accessToString(access_flags, false);
}
/**
* Convert bit field of flags into string such as `static final'.
*
* Special case: Classes compiled with new compilers and with the
* `ACC_SUPER' flag would be said to be "synchronized". This is
* because SUN used the same value for the flags `ACC_SUPER' and
* `ACC_SYNCHRONIZED'.
*
* @param access_flags Access flags
* @param for_class access flags are for class qualifiers ?
* @return String representation of flags
*/
public static final String accessToString(int access_flags,
boolean for_class)
{
StringBuffer buf = new StringBuffer();
int p = 0;
for(int i=0; p < MAX_ACC_FLAG; i++) { // Loop through known flags
p = pow2(i);
if((access_flags & p) != 0) {
/* Special case: Classes compiled with new compilers and with the
* `ACC_SUPER' flag would be said to be "synchronized". This is
* because SUN used the same value for the flags `ACC_SUPER' and
* `ACC_SYNCHRONIZED'.
*/
if(for_class && ((p == ACC_SUPER) || (p == ACC_INTERFACE)))
continue;
buf.append(ACCESS_NAMES[i] + " ");
}
}
return buf.toString().trim();
}
/**
* @return "class" or "interface", depending on the ACC_INTERFACE flag
*/
public static final String classOrInterface(int access_flags) {
return ((access_flags & ACC_INTERFACE) != 0)? "interface" : "class";
}
/**
* Disassemble a byte array of JVM byte codes starting from code line
* `index' and return the dissambled string representation. Decode only
* `num' opcodes (including their operands), use -1 if you want to
* decompile everything.
*
* @param code byte code array
* @param constant_pool Array of constants
* @param index offset in `code' array
* (number of opcodes, not bytes!)
* @param length number of opcodes to decompile, -1 for all
* @return String representation of byte codes
*/
public static final String codeToString(byte[] code,
ConstantPool constant_pool,
int index, int length)
{
StringBuffer buf = new StringBuffer();
ByteSequence stream = new ByteSequence(code);
try {
for(int i=0; i < index; i++) // Skip `index' lines of code
codeToString(stream, constant_pool);
for(int i=0; stream.available() > 0; i++) {
if((length < 0) || (i < length)) {
String indices = fillup(i + "(" + stream.getIndex() + "):", 16, true, ' ');
buf.append(indices + codeToString(stream, constant_pool) + '\n');
}
}
} catch(IOException e) {
System.out.println(buf.toString());
e.printStackTrace();
throw new ClassFormatError("Byte code error: " + e);
}
return buf.toString();
}
/**
* Disassemble a stream of byte codes and return the
* string representation.
*
* @param stream data input stream
* @param constant_pool Array of constants
* @return String representation of byte code
*/
public static final String codeToString(ByteSequence bytes,
ConstantPool constant_pool)
throws IOException
{
short opcode = (short)bytes.readUnsignedByte();
int default_offset=0, low, high, npairs;
int index, vindex, constant;
int[] match, jump_table;
int no_pad_bytes=0, offset;
StringBuffer buf = new StringBuffer(OPCODE_NAMES[opcode]);
/* Special case: Skip (0-3) padding bytes, i.e. the
* following bytes are 4-byte-aligned
*/
if((opcode == TABLESWITCH) || (opcode == LOOKUPSWITCH)) {
int remainder = bytes.getIndex() % 4;
no_pad_bytes = (remainder == 0)? 0 : 4 - remainder;
for(int i=0; i < no_pad_bytes; i++) {
byte b;
if((b=bytes.readByte()) != 0)
System.err.println("Ooops. Padding byte != 0 " + b);
}
// Both cases have a field default_offset in common
default_offset = bytes.readInt();
}
switch(opcode) {
/* Table switch has variable length arguments.
*/
case TABLESWITCH:
low = bytes.readInt();
high = bytes.readInt();
offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
default_offset += offset;
buf.append("\tdefault = " + default_offset + ", low = " + low +
", high = " + high + "(");
jump_table = new int[high - low + 1];
for(int i=0; i < jump_table.length; i++) {
jump_table[i] = offset + bytes.readInt();
buf.append(jump_table[i]);
if(i < jump_table.length - 1)
buf.append(", ");
}
buf.append(")");
break;
/* Lookup switch has variable length arguments.
*/
case LOOKUPSWITCH: {
npairs = bytes.readInt();
offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
match = new int[npairs];
jump_table = new int[npairs];
default_offset += offset;
buf.append("\tdefault = " + default_offset + ", npairs = " + npairs +
" (");
for(int i=0; i < npairs; i++) {
match[i] = bytes.readInt();
jump_table[i] = offset + bytes.readInt();
buf.append("(" + match[i] + ", " + jump_table[i] + ")");
if(i < npairs - 1)
buf.append(", ");
}
buf.append(")");
}
break;
/* Two address bytes + offset from start of byte stream form the
* jump target
*/
case GOTO: case IFEQ: case IFGE: case IFGT:
case IFLE: case IFLT:
case IFNE: case IFNONNULL: case IFNULL: case IF_ACMPEQ:
case IF_ACMPNE: case IF_ICMPEQ: case IF_ICMPGE: case IF_ICMPGT:
case IF_ICMPLE: case IF_ICMPLT: case IF_ICMPNE: case JSR:
buf.append("\t#" + ((bytes.getIndex() - 1) + bytes.readShort()));
break;
/* 32-bit wide jumps
*/
case GOTO_W: case JSR_W:
buf.append("\t#" + ((bytes.getIndex() - 1) + bytes.readInt()));
break;
/* Index byte references local variable (register)
*/
case ALOAD: case ASTORE: case DLOAD: case DSTORE: case FLOAD:
case FSTORE: case ILOAD: case ISTORE: case LLOAD: case LSTORE:
case RET:
if(wide) {
vindex = bytes.readUnsignedShort();
wide=false; // Clear flag
}
else
vindex = bytes.readUnsignedByte();
buf.append("\t\t%" + vindex);
break;
/*
* Remember wide byte which is used to form a 16-bit address in the
* following instruction. Relies on that the method is called again with
* the following opcode.
*/
case WIDE:
wide = true;
buf.append("\t(wide)");
break;
/* Array of basic type.
*/
case NEWARRAY:
buf.append("\t<" + TYPE_NAMES[bytes.readByte()] + ">");
break;
/* Access object/class fields.
*/
case GETFIELD: case GETSTATIC: case PUTFIELD: case PUTSTATIC:
index = bytes.readUnsignedShort();
buf.append("\t" +
constant_pool.constantToString(index, CONSTANT_Fieldref) +
" (" + index + ")");
break;
/* Operands are references to classes in constant pool
*/
case CHECKCAST: case INSTANCEOF: case NEW:
index = bytes.readUnsignedShort();
buf.append("\t<" + constant_pool.constantToString(index,
CONSTANT_Class) +
"> (" + index + ")");
break;
/* Operands are references to methods in constant pool
*/
case INVOKESPECIAL: case INVOKESTATIC: case INVOKEVIRTUAL:
index = bytes.readUnsignedShort();
buf.append("\t" + constant_pool.constantToString(index,
CONSTANT_Methodref) +
" (" + index + ")");
break;
case INVOKEINTERFACE:
index = bytes.readUnsignedShort();
int nargs = bytes.readUnsignedByte(); // historical, redundant
buf.append("\t" +
constant_pool.constantToString(index,
CONSTANT_InterfaceMethodref) +
"() (" + index + ")\t" + nargs + "\t" +
bytes.readUnsignedByte()); // Last byte is a reserved space
break;
/* Operands are references to items in constant pool
*/
case LDC_W: case LDC2_W:
index = bytes.readUnsignedShort();
buf.append("\t\t" + constant_pool.constantToString
(index, constant_pool.getConstant(index).getTag()) +
" (" + index + ")");
break;
case LDC:
index = bytes.readUnsignedByte();
buf.append("\t\t" +
constant_pool.constantToString
(index, constant_pool.getConstant(index).getTag()) +
" (" + index + ")");
break;
/* Array of references.
*/
case ANEWARRAY:
index = bytes.readUnsignedShort();
buf.append("\t<" + compactClassName(constant_pool.getConstantString
(index, CONSTANT_Class), false) +
"> (" + index + ")");
break;
/* Multidimensional array of references.
*/
case MULTIANEWARRAY: {
index = bytes.readUnsignedShort();
int dimensions = bytes.readUnsignedByte();
buf.append("\t<" + compactClassName(constant_pool.getConstantString
(index, CONSTANT_Class), false) +
">\t" + dimensions + " (" + index + ")");
}
break;
/* Increment local variable.
*/
case IINC:
if(wide) {
vindex = bytes.readUnsignedShort();
constant = bytes.readShort();
wide = false;
}
else {
vindex = bytes.readUnsignedByte();
constant = bytes.readByte();
}
buf.append("\t\t%" + vindex + "\t" + constant);
break;
default:
if(NO_OF_OPERANDS[opcode] > 0) {
for(int i=0; i < TYPE_OF_OPERANDS[opcode].length; i++) {
buf.append("\t\t");
switch(TYPE_OF_OPERANDS[opcode][i]) {
case T_BYTE: buf.append(bytes.readUnsignedByte()); break;
case T_SHORT: buf.append(bytes.readShort()); break;
case T_INT: buf.append(bytes.readInt()); break;
default: // Never reached
System.err.println("Unreachable default case reached!");
System.exit(-1);
}
}
}
}
//System.out.println("ret:" + buf.toString());
return buf.toString();
}
/**
* Shorten long class names, java/lang/String becomes
* String.
*
* @param str The long class name
* @return Compacted class name
*/
public static final String compactClassName(String str) {
return compactClassName(str, true);
}
/**
* Shorten long class name str, i.e. chop off the prefix,
* if the
* class name starts with this string and the flag chopit is true.
* Slashes / are converted to dots ..
*
* @param str The long class name
* @param prefix The prefix the get rid off
* @param chopit Flag that determines whether chopping is executed or not
* @return Compacted class name
*/
public static final String compactClassName(String str,
String prefix,
boolean chopit)
{
int len = prefix.length();
str = str.replace('/', '.'); // Is `/' on all systems, even DOS
if(chopit) {
// If string starts with `prefix' and contains no further dots
if(str.startsWith(prefix) &&
(str.substring(len).indexOf('.') == -1))
str = str.substring(len);
}
return str;
}
/**
* Shorten long class names, java/lang/String becomes
* java.lang.String,
* e.g.. If chopit is true the prefix java.lang
* is also removed.
*
* @param str The long class name
* @param chopit Flag that determines whether chopping is executed or not
* @return Compacted class name
*/
public static final String compactClassName(String str, boolean chopit) {
return compactClassName(str, "java.lang.", chopit);
}
private static final boolean is_digit(char ch)
{
return (ch >= '0') && (ch <= '9');
}
private static final boolean is_space(char ch)
{
return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
}
/**
* Converts string containing the method return and argument types
* to a byte code method signature.
*
* @param ret Return type of method
* @param argv Types of method arguments
* @return Byte code representation of method type
*/
public final static String methodTypeToSignature(String ret, String[] argv)
throws ClassFormatError
{
StringBuffer buf = new StringBuffer("(");
String str;
if(argv != null)
for(int i=0; i < argv.length; i++) {
str = typeToSignature(argv[i]);
if(str.endsWith("V")) // void can't be a method argument
throw new ClassFormatError("Invalid type: " + argv[i]);
buf.append(str);
}
str = typeToSignature(ret);
buf.append(")" + str);
return buf.toString();
}
/**
* Gets Java conformant type like `String[]' and returns a string containing
* the type in byte code format, i.e. String[] becomes [Ljava/lang/String;
*
* @param str Type string like int[][]
* @return Byte code representation of type like [[I
*/
public final static String typeToSignature(String str)
throws ClassFormatError
{
int index = str.indexOf('[');
String type, array=null, code=null;
try {
if(index > -1) { // Is an array?
type = str.substring(0, index);
array = str.substring(index);
}
else
type = str;
if(array == null) // Not an array
array = "";
else {
StringBuffer buf = new StringBuffer();
char ch, lastchar='X';
for(int i=0; i < array.length(); i++) {
ch = array.charAt(i);
if(ch == '[')
buf.append('[');
else if((ch == ']') || is_space(ch)) // Ignore
;
else if(is_digit(ch)) {
if((lastchar == '[') || is_digit(lastchar)) // Then it's OK
buf.append(ch);
else
throw new ClassFormatError("Invalid type: " + str);
}
else
throw new ClassFormatError("Invalid type: " + str);
lastchar = ch;
}
array = buf.toString();
}
} catch(StringIndexOutOfBoundsException e) {
throw new ClassFormatError("Invalid type: " + str);
}
int i;
for(i=T_BOOLEAN; i <= T_VOID; i++) {
if(type.equals(TYPE_NAMES[i])) {
code = SHORT_TYPE_NAMES[i];
break;
}
}
if(i == T_VOID) {
if(array.startsWith("[")) // Array of void !?
throw new ClassFormatError("Invalid type: " + str);
}
else if(i > T_VOID) // Interpret as class name
code = "L" + type.replace('.', '/') + ";";
return array + code;
}
/**
* @param signature Method signature
* @return Array of argument types
* @throw ClassFormatError
*/
public static final String[] methodSignatureArgumentTypes(String signature)
throws ClassFormatError
{
return methodSignatureArgumentTypes(signature, true);
}
/**
* @param signature Method signature
* @param chopit Shorten class names ?
* @return Array of argument types
* @throw ClassFormatError
*/
public static final String[] methodSignatureArgumentTypes(String signature,
boolean chopit)
throws ClassFormatError
{
Vector vec = new Vector();
int index;
String[] types;
try { // Read all declarations between for `(' and `)'
if(signature.charAt(0) != '(')
throw new ClassFormatError("Invalid method signature: " + signature);
index = 1; // current string position
while(signature.charAt(index) != ')') {
vec.addElement(signatureToString(signature.substring(index), chopit));
index += consumed_chars; // update position
}
} catch(StringIndexOutOfBoundsException e) { // Should never occur
throw new ClassFormatError("Invalid method signature: " + signature);
}
types = new String[vec.size()];
vec.copyInto(types);
return types;
}
/**
* @param signature Method signature
* @return return type of method
* @throw ClassFormatError
*/
public static final String methodSignatureReturnType(String signature)
throws ClassFormatError
{
return methodSignatureReturnType(signature, true);
}
/**
* @param signature Method signature
* @param chopit Shorten class names ?
* @return return type of method
* @throw ClassFormatError
*/
public static final String methodSignatureReturnType(String signature,
boolean chopit)
throws ClassFormatError
{
int index;
String type;
try {
// Read return type after `)'
index = signature.lastIndexOf(')') + 1;
type = signatureToString(signature.substring(index), chopit);
} catch(StringIndexOutOfBoundsException e) { // Should never occur
throw new ClassFormatError("Invalid method signature: " + signature);
}
return type;
}
/**
* Converts method signature to string with all class names compacted.
*
* @param signature to convert
* @param name of method
* @param access flags of method
* @return Human readable signature
*/
public static final String methodSignatureToString(String signature,
String name,
String access) {
return methodSignatureToString(signature, name, access, true);
}
/**
* A returntype signature represents the return value from a method.
* It is a series of bytes in the following grammar:
*
* ::= | V
*
* The character V indicates that the method returns no value. Otherwise, the
* signature indicates the type of the return value.
* An argument signature represents an argument passed to a method:
*
* ::=
*
* A method signature represents the arguments that the method expects, and
* the value that it returns.
* ::= ()
* ::= *
*
* This method converts such a string into a Java type declaration like
* `void main(String[])' and throws a `ClassFormatError' when the parsed
* type is invalid.
*
* @param signature Method signature
* @param name Method name
* @param access Method access rights
* @return Java type declaration
* @throw ClassFormatError
*/
public static final String methodSignatureToString(String signature,
String name,
String access,
boolean chopit)
throws ClassFormatError
{
StringBuffer buf = new StringBuffer("(");
String type;
int index;
try { // Read all declarations between for `(' and `)'
if(signature.charAt(0) != '(')
throw new ClassFormatError("Invalid method signature: " + signature);
index = 1; // current string position
while(signature.charAt(index) != ')') {
buf.append(signatureToString(signature.substring(index), chopit) +
", ");
index += consumed_chars; // update position
}
index++; // update position
// Read return type after `)'
type = signatureToString(signature.substring(index), chopit);
} catch(StringIndexOutOfBoundsException e) { // Should never occur
throw new ClassFormatError("Invalid method signature: " + signature);
}
if(buf.length() > 1) // Tack off the extra ", "
buf.setLength(buf.length() - 2);
buf.append(")");
return access + ((access.length() > 0)?" " : "") + // May be an empty string
type + " " + name + buf.toString();
}
// Guess what this does
private static final int pow2(int n)
{
return 1 << n;
}
/**
* Replace all occurences of old in str with new.
*
* @param str String to permute
* @param old String to be replaced
* @param new Replacement string
* @return new String object
*/
public static final String replace(String str, String old, String new_) {
int index, old_index;
StringBuffer buf = new StringBuffer();;
try {
if((index = str.indexOf(old)) != -1) { // `old' found in str
old_index = 0; // String start offset
// While we have something to replace
while((index = str.indexOf(old, old_index)) != -1) {
buf.append(str.substring(old_index, index)); // append prefix
buf.append(new_); // append replacement
old_index = index + old.length(); // Skip `old'.length chars
}
buf.append(str.substring(old_index)); // append rest of string
str = buf.toString();
}
else
return str; // Nothing changed
} catch(StringIndexOutOfBoundsException e) { // Should not occur
System.err.println(e);
}
return buf.toString();
}
/**
* Converts signature to string with all class names compacted.
*
* @param signature to convert
* @return Human readable signature
*/
public static final String signatureToString(String signature) {
return signatureToString(signature, true);
}
/**
* The field signature represents the value of an argument to a function or
* the value of a variable. It is a series of bytes generated by the
* following grammar:
*
* ::=
* ::= ||
* ::= B|C|D|F|I|J|S|Z
* ::= L;
* ::= [
* ::= [09]*
*
* The meaning of the base types is as follows:
* B byte signed byte
* C char character
* D double double precision IEEE float
* F float single precision IEEE float
* I int integer
* J long long integer
* L; ... an object of the given class
* S short signed short
* Z boolean true or false
* [ ... array
*
* This method converts this string into a Java type declaration such as
* `String[]' and throws a `ClassFormatError' when the parsed type is
* invalid.
*
* @param signature Class signature
* @return Java type declaration
* @throw ClassFormatError
*/
public static final String signatureToString(String signature,
boolean chopit)
throws ClassFormatError
{
consumed_chars = 1; // This is the default, read just one char like `B'
try {
switch(signature.charAt(0)) {
case 'B' : return "byte";
case 'C' : return "char";
case 'D' : return "double";
case 'F' : return "float";
case 'I' : return "int";
case 'J' : return "long";
case 'L' : { // Full class name
int index = signature.indexOf(';'); // Look for closing `;'
if(index < 0)
throw new ClassFormatError("Invalid signature: " + signature);
consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed
return compactClassName(signature.substring(1, index), chopit);
}
case 'S' : return "short";
case 'Z' : return "boolean";
case '[' : { // Array declaration
int n;
StringBuffer buf, brackets;
String type;
char ch;
int consumed_chars; // Shadows global var
brackets = new StringBuffer(); // Accumulate []'s
// Count opening brackets and look for optional size argument
for(n=0; n < signature.length(); n++) {
ch = signature.charAt(n);
if(ch != '[')
break;
brackets.append('[');
/* If this raises an exception the signature is invalid anyway,
* because `[' must be followed by non-null `'
*/
ch = signature.charAt(++n);
if(is_digit(ch)) { // Check for optional size argument
buf = new StringBuffer();
// Append all digits
for(;is_digit(ch); ch = signature.charAt(++n))
buf.append(ch);
brackets.append(buf.toString()); // Add size
}
n--; // Reset value since it is incremented by the for loop
brackets.append(']'); // Close nesting level
}
consumed_chars = n; // Remember value
// The rest of the string denotes a `'
type = signatureToString(signature.substring(n), chopit);
Utility.consumed_chars += consumed_chars;
return type + brackets.toString();
}
case 'V' : return "void";
default : throw new ClassFormatError("Invalid signature: `" +
signature + "'");
}
} catch(StringIndexOutOfBoundsException e) { // Should never occur
throw new ClassFormatError("Invalid signature: " + e + ":" + signature);
}
}
/**
* Return type of method signature as a byte value as defined in Constants
*
* @param signature in format described above
* @return type of method signature
* @see Constants
*/
public static final byte typeOfMethodSignature(String signature)
throws ClassFormatError
{
int index;
try {
if(signature.charAt(0) != '(')
throw new ClassFormatError("Invalid method signature: " + signature);
index = signature.lastIndexOf(')') + 1;
return typeOfSignature(signature.substring(index));
} catch(StringIndexOutOfBoundsException e) {
throw new ClassFormatError("Invalid method signature: " + signature);
}
}
/**
* Return type of signature as a byte value as defined in Constants
*
* @param signature in format described above
* @return type of signature
* @see Constants
*/
public static final byte typeOfSignature(String signature)
throws ClassFormatError
{
try {
switch(signature.charAt(0)) {
case 'B' : return T_BYTE;
case 'C' : return T_CHAR;
case 'D' : return T_DOUBLE;
case 'F' : return T_FLOAT;
case 'I' : return T_INT;
case 'J' : return T_LONG;
case 'L' : return T_REFERENCE;
case '[' : return T_ARRAY;
case 'V' : return T_VOID;
case 'Z' : return T_BOOLEAN;
case 'S' : return T_SHORT;
default:
throw new ClassFormatError("Invalid method signature: " + signature);
}
} catch(StringIndexOutOfBoundsException e) {
throw new ClassFormatError("Invalid method signature: " + signature);
}
}
/**
* Convert (signed) byte to (unsigned) short value, i.e. all negative
* values become positive.
*/
private static final short byteToShort(byte b) {
return (b < 0)? (short)(256 + b) : (short)b;
}
/*
* @return bytes as hexidecimal string, e.g. 00 FA 12 ...
*/
public static final String toHexString(byte[] bytes) {
StringBuffer buf = new StringBuffer();
for(int i=0; i < bytes.length; i++) {
short b = byteToShort(bytes[i]);
String hex = Integer.toString(b, 0x10);
if(b < 0x10) // just one digit, prepend '0'
buf.append('0');
buf.append(hex);
if(i < bytes.length - 1)
buf.append(' ');
}
return buf.toString();
}
/**
* Return a string for an integer justified left or right and filled up with
* `fill' characters if necessary.
*
* @param i integer to format
* @param length length of desired string
* @param left format left or right
* @param fill fill character
* @return formatted int
*/
public static final String format(int i, int length, boolean left, char fill) {
return fillup(Integer.toString(i), length, left, fill);
}
/**
* Fillup char with up to length characters with char `fill' and justify it left or right.
*
* @param str string to format
* @param length length of desired string
* @param left format left or right
* @param fill fill character
* @return formatted string
*/
public static final String fillup(String str, int length, boolean left_justify, char fill) {
int len = length - str.length();
char[] buf = new char[(len < 0)? 0 : len];
for(int j=0; j < buf.length; j++)
buf[j] = fill;
if(left_justify)
return str + new String(buf);
else
return new String(buf) + str;
}
static final boolean equals(byte[] a, byte[] b) {
int size;
if((size=a.length) != b.length)
return false;
for(int i=0; i < size; i++)
if(a[i] != b[i])
return false;
return true;
}
public static final void printArray(PrintStream out, Object[] obj) {
out.println(printArray(obj, true));
}
public static final void printArray(PrintWriter out, Object[] obj) {
out.println(printArray(obj, true));
}
public static final String printArray(Object[] obj) {
return printArray(obj, true);
}
public static final String printArray(Object[] obj, boolean braces) {
if(obj == null)
return null;
StringBuffer buf = new StringBuffer();
if(braces)
buf.append('{');
for(int i=0; i < obj.length; i++) {
if(obj[i] != null)
buf.append(obj[i].toString());
else
buf.append("null");
if(i < obj.length - 1)
buf.append(", ");
}
if(braces)
buf.append('}');
return buf.toString();
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantInterfaceMethodref.java 100644 157 13 2726 6613136452 24206 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents a constant pool reference to an interface method.
*
* @version $Id: ConstantInterfaceMethodref.java,v 1.1 1998/07/01 13:08:23 dahm Exp $
* @author M. Dahm
*/
public final class ConstantInterfaceMethodref extends ConstantCP {
/**
* Initialize from another object.
*/
public ConstantInterfaceMethodref(ConstantInterfaceMethodref c) {
super(CONSTANT_InterfaceMethodref, c.getClassIndex(), c.getNameAndTypeIndex());
}
/**
* Initialize instance from file data.
*
* @param file input stream
* @throw IOException
*/
ConstantInterfaceMethodref(DataInputStream file) throws IOException
{
super(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(CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
}
/**
* 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.visitConstantInterfaceMethodref(this);
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/LineNumberTable.java 100644 157 13 11607 6600423003 21747 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and represents a table of
* line numbers for debugging purposes. This attribute is used by the
* Code attribute. It contains pairs of PCs and line numbers.
*
* @version $Id: LineNumberTable.java,v 1.6 1998/09/18 09:21:07 dahm Exp $
* @author M. Dahm
* @see Code
* @see LineNumber
*/
public final class LineNumberTable extends Attribute {
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 clone() for a physical copy.
*/
public LineNumberTable(LineNumberTable c) {
this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(),
c.getConstantPool());
}
/*
* @param name_index Index of name
* @param length Content length in bytes
* @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(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
* @throw IOException
* @param constant_pool Array of constants
*/
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);
}
/**
* 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.visitLineNumberTable(this);
}
/**
* Dump line number table attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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);
}
/**
* @return Array of (pc offset, line number) pairs.
*/
public final LineNumber[] getLineNumberTable() { return line_number_table; }
/**
* @param line_number_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("");
for(int i=0; i < line_number_table_length; i++) {
buf.append(line_number_table[i].toString());
if(i < line_number_table_length - 1)
buf.append(", ");
}
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) // array is empty
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) // else constrain search area
r = i - 1;
else // pos > j
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);
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; }
}
JavaClass/DE/fub/inf/JVM/JavaClass/Attribute.java 100644 157 13 14152 6546432274 20723 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* Abstract super class for Attribute objects. Currently the
* ConstantValue, SourceFile, Code,
* Exceptiontable, LineNumberTable,
* LocalVariableTable, InnerClasses and
* Synthetic attributes are supported. The
* Unknown attribute stands for non-standard-attributes.
*
* @version $Id: Attribute.java,v 1.1 1998/07/01 13:08:12 dahm Exp $
* @author M. Dahm
* @see ConstantValue
* @see SourceFile
* @see Code
* @see Unknown
* @see ExceptionTable
* @see LineNumberTable
* @see LocalVariableTable
* @see InnerClasses
* @see Synthetic
* @see Deprecated
*/
public abstract class Attribute implements Constants, Cloneable
{
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;
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;
}
/**
* 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);
/**
* Dump attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
public void dump(DataOutputStream file) throws IOException
{
file.writeShort(name_index);
file.writeInt(length);
}
/* 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
* @throw IOException
* @throw ClassFormatError
* @throw InternalError
*/
static final Attribute readAttribute(DataInputStream file,
ConstantPool constant_pool)
throws IOException, ClassFormatError, InternalError
{
ConstantUtf8 c;
String name;
int name_index;
int length;
byte tag = ATTR_UNKNOWN; // Unknown attribute
// Get class name from constant pool via `name_index' indirection
name_index = (int)(file.readUnsignedShort());
c = (ConstantUtf8)constant_pool.getConstant(name_index,
CONSTANT_Utf8);
name = c.getBytes();
// Length of data in bytes
length = file.readInt();
// Compare strings to find known attribute
for(byte i=0; i < KNOWN_ATTRIBUTES; i++) {
if(name.equals(ATTRIBUTE_NAMES[i])) {
tag = i; // found!
break;
}
}
// Call proper constructor, depending on `tag'
switch(tag) {
case ATTR_UNKNOWN:
return new Unknown(name_index, length, file, constant_pool);
case ATTR_CONSTANT_VALUE:
return new ConstantValue(name_index, length, file, constant_pool);
case ATTR_SOURCE_FILE:
return new SourceFile(name_index, length, file, constant_pool);
case ATTR_CODE:
return new Code(name_index, length, file, constant_pool);
case ATTR_EXCEPTIONS:
return new ExceptionTable(name_index, length, file, constant_pool);
case ATTR_LINE_NUMBER_TABLE:
return new LineNumberTable(name_index, length, file, constant_pool);
case ATTR_LOCAL_VARIABLE_TABLE:
return new LocalVariableTable(name_index, length, file, constant_pool);
case ATTR_INNER_CLASSES:
return new InnerClasses(name_index, length, file, constant_pool);
case ATTR_SYNTHETIC:
return new Synthetic(name_index, length, file, constant_pool);
case ATTR_DEPRECATED:
return new Deprecated(name_index, length, file, constant_pool);
case ATTR_PMG:
return new PMGClass(name_index, length, file, constant_pool);
default: // Never reached
throw new InternalError("Ooops! default case reached.");
}
}
/**
* @return Length of attribute field in bytes.
*/
public final int getLength() { return length; }
/**
* @param Attribute length in bytes.
*/
public final void setLength(int length) {
this.length = length;
}
/**
* @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 ATTRIBUTE_NAMES[tag];
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Synthetic.java 100644 157 13 5615 6546432335 20714 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and declares this class
* as `synthetic', i.e. it needs special handling.
* It is instantiated from the Attribute.readAttribute() method.
*
* @version $Id: Synthetic.java,v 1.1 1998/07/01 13:08:45 dahm Exp $
* @author M. Dahm
* @see Attribute
*/
public final class Synthetic extends Attribute
{
private byte[] bytes;
/**
* Initialize from another object. Note that both objects use the same
* references (shallow copy). Use clone() for a physical copy.
*/
public Synthetic(Synthetic c) {
this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
}
/**
* @param name_index Index in constant pool to CONSTANT_Utf8
* @param length Content length in bytes
* @param bytes Attribute contents
* @param constant_pool Array of constants
* @param sourcefile_index Index in constant pool to CONSTANT_Utf8
*/
public Synthetic(int name_index, int length, byte[] bytes,
ConstantPool constant_pool)
{
super(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
* @throw 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");
}
}
/**
* 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.visitSynthetic(this);
}
/**
* Dump source file attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
super.dump(file);
if(length > 0)
file.write(bytes, 0, length);
}
/**
* @return data bytes.
*/
public final byte[] getBytes() { return bytes; }
/**
* @param bytes.
*/
public final void setBytes(byte[] bytes) {
this.bytes = bytes;
}
/**
* @return deep copy of this attribute
*/
public Attribute copy(ConstantPool constant_pool) {
Synthetic c = (Synthetic)clone();
if(bytes != null)
c.bytes = (byte[])bytes.clone();
c.constant_pool = constant_pool;
return c;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantString.java 100644 157 13 4216 6546432314 21713 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to a String object.
*
* @version $Id: ConstantString.java,v 1.1 1998/07/01 13:08:28 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantString extends Constant {
private int string_index; // Identical to ConstantClass except for this name
/**
* Initialize from another object.
*/
public ConstantString(ConstantString c) {
this(c.getStringIndex());
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantString(DataInputStream file) throws IOException
{
this((int)file.readUnsignedShort());
}
/**
* @param string_index Index of Constant_Utf8 in constant pool
*/
public ConstantString(int string_index)
{
super(CONSTANT_String);
this.string_index = string_index;
}
/**
* 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.visitConstantString(this);
}
/**
* Dump constant field reference to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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.
*/
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 + ")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Constant.java 100644 157 13 6576 6546434243 20542 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* Abstract superclass for classes to represent the different constant types
* in the constant pool of a class file. The classes keep closely to
* the JVM specification.
*
* @version $Id: Constant.java,v 1.2 1998/07/01 13:24:51 dahm Exp $
* @author M. Dahm
* @see ConstantClass
* @see ConstantFieldref
* @see ConstantMethodref
* @see ConstantInterfaceMethodref
* @see ConstantString
* @see ConstantInteger
* @see ConstantFloat
* @see ConstantLong
* @see ConstantDouble
* @see ConstantNameAndType
* @see ConstantUtf8
* @see ConstantUnicode
*/
public abstract class Constant implements Constants, Cloneable {
/* 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;
Constant(byte tag) { this.tag = 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
*/
public abstract void accept(Visitor v);
public abstract void dump(DataOutputStream file) throws IOException;
/**
* @return Tag of constant, i.e. its type. No setTag() method to avoid
* confusion.
*/
public final byte getTag() { return tag; }
/**
* @return String representation.
*/
public String toString() {
return CONSTANT_NAMES[tag] + "[" + tag + "]";
}
/**
* @return deep copy of this constant
*/
public Constant copy() {
try {
return (Constant)clone();
} catch(CloneNotSupportedException e) {}
return null;
}
/**
* 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, ClassFormatError
{
byte b = file.readByte(); // Read tag byte
switch(b) {
case CONSTANT_Class: return new ConstantClass(file);
case CONSTANT_Fieldref: return new ConstantFieldref(file);
case CONSTANT_Methodref: return new ConstantMethodref(file);
case CONSTANT_InterfaceMethodref: return new
ConstantInterfaceMethodref(file);
case CONSTANT_String: return new ConstantString(file);
case CONSTANT_Integer: return new ConstantInteger(file);
case CONSTANT_Float: return new ConstantFloat(file);
case CONSTANT_Long: return new ConstantLong(file);
case CONSTANT_Double: return new ConstantDouble(file);
case CONSTANT_NameAndType: return new ConstantNameAndType(file);
case CONSTANT_Utf8: return new ConstantUtf8(file);
case CONSTANT_Unicode: return new ConstantUnicode(file);
default:
throw new ClassFormatError("Invalid byte tag in constant pool: " + b);
}
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/LocalVariable.java 100644 157 13 13037 6562073241 21452 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class represents a local variable within a method. It contains its
* scope, name, signature and index on the method's frame.
*
* @version $Id: LocalVariable.java,v 1.2 1998/08/05 15:13:37 dahm Exp $
* @author M. Dahm
* @see LocalVariableTable
*/
public final class LocalVariable implements Constants, Cloneable {
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 int slot; /* Variable is `slot'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 clone() for a physical copy.
*/
public LocalVariable(LocalVariable c) {
this(c.getStartPC(), c.getLength(), c.getNameIndex(),
c.getSignatureIndex(), c.getSlot(), c.getConstantPool());
}
/**
* Construct object from file stream.
* @param file Input stream
* @throw IOException
*/
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 slot Variable is `slot'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 slot,
ConstantPool constant_pool)
{
this.start_pc = start_pc;
this.length = length;
this.name_index = name_index;
this.signature_index = signature_index;
this.slot = slot;
this.constant_pool = 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
*/
public void accept(Visitor v) {
v.visitLocalVariable(this);
}
/**
* Dump local variable to file stream in binary format.
*
* @param file Output file stream
* @throw 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(slot);
}
/**
* @return Constant pool used by this object.
* @see ConstantPool
*/
public final ConstantPool getConstantPool() { return constant_pool; }
/**
* @return Variable is valid within getStartPC() .. getStartPC()+getLength()
*/
public final int getLength() { return length; }
/**
* @return Variable name.
*/
public final String getName() {
ConstantUtf8 c;
c = (ConstantUtf8)constant_pool.getConstant(name_index, CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return Index in constant pool of variable name.
*/
public final int getNameIndex() { return name_index; }
/**
* @return Signature.
*/
public final String getSignature() {
ConstantUtf8 c;
c = (ConstantUtf8)constant_pool.getConstant(signature_index,
CONSTANT_Utf8);
return c.getBytes();
}
/**
* @return Index in constant pool of variable signature.
*/
public final int getSignatureIndex() { return signature_index; }
/**
* @return Variable is `getSlot()'th local variable on this method's frame.
*/
public final int getSlot() { return slot; }
/**
* @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.
* @see ConstantPool
*/
public final void setConstantPool(ConstantPool constant_pool) {
this.constant_pool = constant_pool;
}
/**
* @param length.
*/
public final void setLength(int length) {
this.length = length;
}
/**
* @param name_index.
*/
public final void setNameIndex(int name_index) {
this.name_index = name_index;
}
/**
* @param signature_index.
*/
public final void setSignatureIndex(int signature_index) {
this.signature_index = signature_index;
}
/**
* @param slot.
*/
public final void setSlot(int slot) {
this.slot = slot;
}
/**
* @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 +
", slot = " + slot + ":" + signature + " " + name + ")";
}
/**
* @return deep copy of this object
*/
public LocalVariable copy() {
try {
return (LocalVariable)clone();
} catch(CloneNotSupportedException e) {}
return null;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Visitor.java 100644 157 13 4244 6565771141 20400 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
/**
* Interface to make use of the Visitor pattern programming style.
* I.e. a class that implements this interface can traverse the contents of
* a Java class just by calling the `accept' method which all classes have.
*
* Implemented by wish of
* Boris Bokowski.
*
* @version $Id: Visitor.java,v 1.2 1998/08/17 09:05:37 dahm Exp $
* @author M. Dahm
*/
public interface Visitor {
public void visitCode(Code obj);
public void visitCodeException(CodeException obj);
public void visitConstantClass(ConstantClass obj);
public void visitConstantDouble(ConstantDouble obj);
public void visitConstantFieldref(ConstantFieldref obj);
public void visitConstantFloat(ConstantFloat obj);
public void visitConstantInteger(ConstantInteger obj);
public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj);
public void visitConstantLong(ConstantLong obj);
public void visitConstantMethodref(ConstantMethodref obj);
public void visitConstantNameAndType(ConstantNameAndType obj);
public void visitConstantPool(ConstantPool obj);
public void visitConstantString(ConstantString obj);
public void visitConstantUnicode(ConstantUnicode obj);
public void visitConstantUtf8(ConstantUtf8 obj);
public void visitConstantValue(ConstantValue obj);
public void visitDeprecated(Deprecated 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 visitSourceFile(SourceFile obj);
public void visitSynthetic(Synthetic obj);
public void visitUnknown(Unknown obj);
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantDouble.java 100644 157 13 3644 6546432303 21661 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to a Double object.
*
* @version $Id: ConstantDouble.java,v 1.1 1998/07/01 13:08:19 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantDouble extends Constant {
private double bytes;
/**
* @param bytes Data
*/
public ConstantDouble(double bytes) {
super(CONSTANT_Double);
this.bytes = bytes;
}
/**
* Initialize from another object.
*/
public ConstantDouble(ConstantDouble c) {
this(c.getBytes());
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantDouble(DataInputStream file) throws IOException
{
this(file.readDouble());
}
/**
* 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.visitConstantDouble(this);
}
/**
* Dump constant double to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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.
*/
public final void setBytes(double bytes) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString()
{
return super.toString() + "(bytes = " + bytes + ")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/LocalVariableTable.java 100644 157 13 10073 6565066071 22425 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from Attribute and represents colection of local
* variables in a method. This attribute is used by the Code attribute.
*
* @version $Id: LocalVariableTable.java,v 1.2 1998/08/14 16:56:25 dahm Exp $
* @author M. Dahm
* @see Code
* @see LocalVariable
*/
public class LocalVariableTable extends Attribute {
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 clone() for a physical copy.
*/
public LocalVariableTable(LocalVariableTable c) {
this(c.getNameIndex(), c.getLength(), c.getLocalVariableTable(),
c.getConstantPool());
}
/**
* @param name_index Index in constant pool to `LocalVariableTable'
* @param length Content length in bytes
* @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(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
* @throw 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);
}
/**
* 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.visitLocalVariableTable(this);
}
/**
* Dump local variable table attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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);
}
/**
* @return Array of local variables of method.
*/
public final LocalVariable[] getLocalVariableTable() {
return local_variable_table;
}
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(", ");
}
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; }
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantNameAndType.java 100644 157 13 5353 6546432312 22613 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to the name and signature
* of a field or method.
*
* @version $Id: ConstantNameAndType.java,v 1.1 1998/07/01 13:08:26 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantNameAndType extends Constant {
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 instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantNameAndType(DataInputStream file) throws IOException
{
this((int)file.readUnsignedShort(), (int)file.readUnsignedShort());
}
/**
* @param name_index Name of field/method
* @param signature_index and its signature
*/
public ConstantNameAndType(int name_index,
int signature_index)
{
super(CONSTANT_NameAndType);
this.name_index = name_index;
this.signature_index = signature_index;
}
/**
* 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.visitConstantNameAndType(this);
}
/**
* Dump name and signature index to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
public final void dump(DataOutputStream file) throws IOException
{
file.writeByte(tag);
file.writeShort(name_index);
file.writeShort(signature_index);
}
/**
* @return Name index in constant pool of field/method name.
*/
public final int getNameIndex() { return name_index; }
/**
* @return Index in constant pool of field/method signature.
*/
public final int getSignatureIndex() { return signature_index; }
/**
* @param name_index.
*/
public final void setNameIndex(int name_index) {
this.name_index = name_index;
}
/**
* @param signature_index.
*/
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 + ")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantInteger.java 100644 157 13 3630 6546432306 22042 0 ustar dahm institut
package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to an int object.
*
* @version $Id: ConstantInteger.java,v 1.1 1998/07/01 13:08:22 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantInteger extends Constant {
private int bytes;
/**
* @param bytes Data
*/
public ConstantInteger(int bytes)
{
super(CONSTANT_Integer);
this.bytes = bytes;
}
/**
* Initialize from another object.
*/
public ConstantInteger(ConstantInteger c) {
this(c.getBytes());
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantInteger(DataInputStream file) throws IOException
{
this(file.readInt());
}
/**
* 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.visitConstantInteger(this);
}
/**
* Dump constant integer to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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.
*/
public final void setBytes(int bytes) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/JavaClass.java 100644 157 13 32561 6600423002 20607 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* Represents a Java class, i.e. the data structures, constant pool,
* fields, methods and commands contained in a Java .class file.
* See JVM
* specification for details.
*
* @version $Id: JavaClass.java,v 1.6 1998/09/18 09:21:06 dahm Exp $
* @author M. Dahm
*/
public class JavaClass implements Constants, Cloneable {
private String file_name;
private String package_name;
private String source_file_name = "";
private int class_name_index;
private int superclass_name_index;
private String class_name;
private String superclass_name;
private int major, minor; // Compiler version
private int access_flags; // Access rights
private ConstantPool constant_pool; // Constant pool
private int[] interfaces; // implemented interfaces
private String[] interface_names;
private Field[] fields; // Fields, i.e. variables of class
private Method[] methods; // methods defined in the class
private Attribute[] attributes; // attributes defined in the class
static boolean debug = false; // Debugging on/off
static char sep = '/'; // directory separator
/**
* Constructor gets all contents as arguments.
*
* @param class_name Class name
* @param superclass_name Superclass name
* @param file_name File name
* @param major Major compiler version
* @param minor Minor compiler version
* @param access_flags Access rights defined by bit flags
* @param constant_pool Array of constants
* @param interfaces Implemented interfaces
* @param fields Class fields
* @param methods Class methods
* @param attributes Class attributes
*/
public JavaClass(int class_name_index,
int superclass_name_index,
String file_name,
int major,
int minor,
int access_flags,
ConstantPool constant_pool,
int[] interfaces,
Field[] fields,
Method[] methods,
Attribute[] attributes)
{
if(interfaces == null) // Allowed for backward compatibility
interfaces = new int[0];
if(attributes == null)
this.attributes = new Attribute[0];
if(fields == null)
fields = new Field[0];
if(methods == null)
methods = new Method[0];
this.class_name_index = class_name_index;
this.superclass_name_index = superclass_name_index;
this.file_name = file_name;
this.major = major;
this.minor = minor;
this.access_flags = access_flags;
this.constant_pool = constant_pool;
this.interfaces = interfaces;
this.fields = fields;
this.methods = methods;
this.attributes = attributes;
// Get source file name if available
for(int i=0; i < attributes.length; i++) {
if(attributes[i] instanceof SourceFile) {
source_file_name = ((SourceFile)attributes[i]).getSourceFileName();
break;
}
}
// Get class name and superclass name
ConstantUtf8 name;
/* According to the specification the following entries must be of type
* `ConstantClass' but we check that anyway via the
* `ConstPool.getConstant' method.
*/
class_name = constant_pool.getConstantString(class_name_index,
CONSTANT_Class);
class_name = Utility.compactClassName(class_name, false);
int index = class_name.lastIndexOf('.');
if(index < 0)
package_name = "";
else
package_name = class_name.substring(0, index);
if(superclass_name_index > 0) { // May be zero -> class is java.lang.Object
superclass_name = constant_pool.getConstantString(superclass_name_index,
CONSTANT_Class);
superclass_name = Utility.compactClassName(superclass_name, false);
}
else
superclass_name = "java.lang.Object";
interface_names = new String[interfaces.length];
for(int i=0; i < interfaces.length; i++) {
String str = constant_pool.getConstantString(interfaces[i], CONSTANT_Class);
interface_names[i] = Utility.compactClassName(str, false);
}
}
/**
* 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.visitJavaClass(this);
}
/* Print debug information depending on `JavaClass.debug'
*/
static final void Debug(String str) {
if(debug)
System.out.println(str);
}
/**
* Dump class to a file, this should create a valid .class file.
*
* @param file Output file
* @throw IOException
*/
public void dump(File file) throws IOException
{
dump(file.getAbsolutePath());
}
/**
* Dump class to a file, this should create a valid .class file.
*
* @param file_name Output file name
* @exception IOException
*/
public void dump(String file_name) throws IOException
{
DataOutputStream file;
file = new DataOutputStream(new FileOutputStream(file_name));
dump(file);
}
/**
* @return class in binary format
*/
public byte[] getBytes() {
ByteArrayOutputStream s = new ByteArrayOutputStream();
DataOutputStream ds = new DataOutputStream(s);
try {
dump(ds);
ds.close();
} catch(IOException e) { e.printStackTrace(); }
return s.toByteArray();
}
/**
* Dump Java class to output stream in binary format.
*
* @param file Output stream
* @exception IOException
*/
public void dump(OutputStream file) throws IOException {
dump(new DataOutputStream(file));
}
/**
* Dump Java class to output stream in binary format.
*
* @param file Output stream
* @exception IOException
*/
public void dump(DataOutputStream file) throws IOException
{
file.writeInt(0xcafebabe);
file.writeShort(minor);
file.writeShort(major);
constant_pool.dump(file);
file.writeShort(access_flags);
file.writeShort(class_name_index);
file.writeShort(superclass_name_index);
file.writeShort(interfaces.length);
for(int i=0; i < interfaces.length; i++)
file.writeShort(interfaces[i]);
file.writeShort(fields.length);
for(int i=0; i < fields.length; i++)
fields[i].dump(file);
file.writeShort(methods.length);
for(int i=0; i < methods.length; i++)
methods[i].dump(file);
if(attributes != null) {
file.writeShort(attributes.length);
for(int i=0; i < attributes.length; i++)
attributes[i].dump(file);
}
else
file.writeShort(0);
file.close();
}
/**
* @return Access rights of class.
*/
public final int getAccessFlags() { return access_flags; }
/**
* @return Attributes of the class.
*/
public final Attribute[] getAttributes() { return attributes; }
/**
* @return Class name.
*/
public final String getClassName() { return class_name; }
/**
* @return Package name.
*/
public final String getPackageName() { return package_name; }
/**
* @return Class name index.
*/
public final int getClassNameIndex() { return class_name_index; }
/**
* @return Constant pool.
*/
public final ConstantPool getConstantPool() { return constant_pool; }
/**
* @return Fields, i.e. variables of the class.
*/
public final Field[] getFields() { return fields; }
/**
* @return File name.
*/
public final String getFileName() { return file_name; }
/**
* @return Names of implemented interfaces.
*/
public final String[] getInterfaceNames() { return interface_names; }
/**
* @return Implemented interfaces.
*/
public final int[] getInterfaces() { return interfaces; }
/**
* @return Major number of compiler version.
*/
public final int getMajor() { return major; }
/**
* @return Methods of the class.
*/
public final Method[] getMethods() { return methods; }
/**
* @return Minor number of compiler version.
*/
public final int getMinor() { return minor; }
/**
* @return File name of source.
*/
public final String getSourceFileName() { return source_file_name; }
/**
* @return Superclass name.
*/
public final String getSuperclassName() { return superclass_name; }
/**
* @return Class name index.
*/
public final int getSuperclassNameIndex() { return superclass_name_index; }
static {
// Debugging ... on/off
String debug = System.getProperty("JavaClass.debug");
if(debug != null)
JavaClass.debug = new Boolean(debug).booleanValue();
// Get path separator either / or \ usually
String sep = System.getProperty("file.separator");
if(sep != null)
try {
JavaClass.sep = sep.charAt(0);
} catch(StringIndexOutOfBoundsException e) {} // Never reached
}
/**
* @param access_flags.
*/
public final void setAccessFlags(int access_flags) {
this.access_flags = access_flags;
}
/**
* @param attributes.
*/
public final void setAttributes(Attribute[] attributes) {
this.attributes = attributes;
}
/**
* @param class_name.
*/
public final void setClassName(String class_name) {
this.class_name = class_name;
}
/**
* @param class_name_index.
*/
public final void setClassNameIndex(int class_name_index) {
this.class_name_index = class_name_index;
}
/**
* @param constant_pool.
*/
public final void setConstantPool(ConstantPool constant_pool) {
this.constant_pool = constant_pool;
}
/**
* @param fields.
*/
public final void setFields(Field[] fields) {
this.fields = fields;
}
/**
* @param file_name.
*/
public final void setFileName(String file_name) {
this.file_name = file_name;
}
/**
* @param interface_names.
*/
public final void setInterfaceNames(String[] interface_names) {
this.interface_names = interface_names;
}
/**
* @param interfaces.
*/
public final void setInterfaces(int[] interfaces) {
this.interfaces = interfaces;
}
/**
* @param major.
*/
public final void setMajor(int major) {
this.major = major;
}
/**
* @param methods.
*/
public final void setMethods(Method[] methods) {
this.methods = methods;
}
/**
* @param minor.
*/
public final void setMinor(int minor) {
this.minor = minor;
}
/**
* @param source_file_name.
*/
public final void setSourceFileName(String source_file_name) {
this.source_file_name = source_file_name;
}
/**
* @param superclass_name.
*/
public final void setSuperclassName(String superclass_name) {
this.superclass_name = superclass_name;
}
/**
* @param superclass_name_index.
*/
public final void setSuperclassNameIndex(int superclass_name_index) {
this.superclass_name_index = superclass_name_index;
}
/**
* @return String representing class contents.
*/
public String toString() {
StringBuffer buf = new StringBuffer();
String access = Utility.accessToString(access_flags, true);
buf.append(access + " " + Utility.classOrInterface(access_flags) + " " +
class_name + " extends " +
Utility.compactClassName(superclass_name, false) + '\n');
int size = interfaces.length;
if(size > 0) {
buf.append("implements\t\t");
for(int i=0; i < size; i++) {
buf.append(interface_names[i]);
if(i < size - 1)
buf.append(", ");
}
buf.append('\n');
}
buf.append("filename\t\t" + file_name + '\n');
buf.append("compiled from\t\t" + source_file_name + '\n');
buf.append("compiler version\t" + major + "." + minor + '\n');
buf.append("access flags\t\t" + access_flags + '\n');
buf.append("constant pool\t\t" + constant_pool.getLength() + " entries\n");
buf.append("ACC_SUPER flag\t\t" + ((access_flags & ACC_SUPER) != 0) + "\n\n");
buf.append(attributes.length + " attributes:\n");
for(int i=0; i < attributes.length; i++)
buf.append("\t" + attributes[i] + '\n');
buf.append(fields.length + " fields:\n");
for(int i=0; i < fields.length; i++)
buf.append("\t" + fields[i] + '\n');
buf.append(methods.length + " methods:\n");
for(int i=0; i < methods.length; i++)
buf.append("\t" + methods[i] + '\n');
buf.append('\n');
return buf.toString();
}
/**
* @return deep copy of this class
*/
public JavaClass copy() {
JavaClass c = null;
try {
c = (JavaClass)clone();
} catch(CloneNotSupportedException e) {}
c.constant_pool = constant_pool.copy();
c.interfaces = (int[])interfaces.clone();
c.interface_names = (String[])interface_names.clone();
c.fields = new Field[fields.length];
for(int i=0; i < fields.length; i++)
c.fields[i] = fields[i].copy(c.constant_pool);
c.methods = new Method[methods.length];
for(int i=0; i < methods.length; i++)
c.methods[i] = methods[i].copy(c.constant_pool);
c.attributes = new Attribute[attributes.length];
for(int i=0; i < attributes.length; i++)
c.attributes[i] = attributes[i].copy(c.constant_pool);
return c;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ExceptionTable.java 100644 157 13 10607 6565771136 21673 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* Class is derived from Attribute and represents the table
* of exceptions that are thrown by a method. This attribute may be used
* once per method.
*
* @version $Id: ExceptionTable.java,v 1.3 1998/08/17 09:05:34 dahm Exp $
* @author M. Dahm
* @see Code
* @see Attribute
*/
public final class ExceptionTable extends Attribute {
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 clone() for a physical copy.
*/
public ExceptionTable(ExceptionTable c) {
this(c.getNameIndex(), c.getLength(), c.getExceptionIndexTable(),
c.getConstantPool());
}
/**
* @param name_index Index in constant pool
* @param length Content length in bytes
* @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(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
* @throw 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();
}
/**
* 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.visitExceptionTable(this);
}
/**
* Dump exceptions attribute to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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]);
}
/**
* @return Array of indices into constant pool of thrown exceptions.
*/
public final int[] getExceptionIndexTable() {return exception_index_table;}
/**
* @return Length of exception table.
*/
public final int getNumberOfExceptions() { 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], CONSTANT_Class).
replace('/', '.');
return names;
}
/**
* @param exception_index_table.
* 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],
CONSTANT_Class);
buf.append(Utility.compactClassName(str));
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();
c.exception_index_table = (int[])exception_index_table.clone();
c.constant_pool = constant_pool;
return c;
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/ConstantLong.java 100644 157 13 3575 6546432310 21347 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
/**
* This class is derived from the abstract
* Constant class
* and represents a reference to a long object.
*
* @version $Id: ConstantLong.java,v 1.1 1998/07/01 13:08:24 dahm Exp $
* @author M. Dahm
* @see Constant
*/
public final class ConstantLong extends Constant {
private long bytes;
/**
* @param bytes Data
*/
public ConstantLong(long bytes)
{
super(CONSTANT_Long);
this.bytes = bytes;
}
/**
* Initialize from another object.
*/
public ConstantLong(ConstantLong c) {
this(c.getBytes());
}
/**
* Initialize instance from file data.
*
* @param file Input stream
* @throw IOException
*/
ConstantLong(DataInputStream file) throws IOException
{
this(file.readLong());
}
/**
* 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.visitConstantLong(this);
}
/**
* Dump constant long to file stream in binary format.
*
* @param file Output file stream
* @throw IOException
*/
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.
*/
public final void setBytes(long bytes) {
this.bytes = bytes;
}
/**
* @return String representation.
*/
public final String toString() {
return super.toString() + "(bytes = " + bytes + ")";
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/DefaultVisitor.java 100644 157 13 11355 6566775525 21741 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
/**
* Traverses a JavaClass with another Visitor object 'piggy-backed'
* that is applied to all components of a JavaClass object. I.e. this
* class supplies the traversal strategy, other classes can make use
* of it.
*
* @version $Id: DefaultVisitor.java,v 1.1 1998/08/20 10:32:53 dahm Exp $
* @author M. Dahm
*/
public class DefaultVisitor implements Visitor {
private JavaClass clazz;
private Visitor visitor;
/**
* @param clazz Class to traverse
* @param visitor visitor object to apply to all components
*/
public DefaultVisitor(JavaClass clazz, Visitor visitor) {
this.clazz = clazz;
this.visitor = visitor;
}
/**
* Start traversal.
*/
public void visit() { clazz.accept(this); }
public void visitJavaClass(JavaClass clazz) {
clazz.accept(visitor);
Field[] fields = clazz.getFields();
for(int i=0; i < fields.length; i++)
fields[i].accept(this);
Method[] methods = clazz.getMethods();
for(int i=0; i < methods.length; i++)
methods[i].accept(this);
Attribute[] attributes = clazz.getAttributes();
for(int i=0; i < attributes.length; i++)
attributes[i].accept(this);
clazz.getConstantPool().accept(this);
}
public void visitField(Field field) {
field.accept(visitor);
Attribute[] attributes = field.getAttributes();
for(int i=0; i < attributes.length; i++)
attributes[i].accept(this);
}
public void visitConstantValue(ConstantValue cv) { cv.accept(visitor); }
public void visitMethod(Method method) {
method.accept(visitor);
Attribute[] attributes = method.getAttributes();
for(int i=0; i < attributes.length; i++)
attributes[i].accept(this);
}
public void visitExceptionTable(ExceptionTable table) { table.accept(visitor); }
public void visitCode(Code code) {
code.accept(visitor);
CodeException[] table = code.getExceptionTable();
for(int i=0; i < table.length; i++)
table[i].accept(this);
Attribute[] attributes = code.getAttributes();
for(int i=0; i < attributes.length; i++)
attributes[i].accept(this);
}
public void visitCodeException(CodeException ce) { ce.accept(visitor); }
public void visitLineNumberTable(LineNumberTable table) {
table.accept(visitor);
LineNumber[] numbers = table.getLineNumberTable();
for(int i=0; i < numbers.length; i++)
numbers[i].accept(this);
}
public void visitLineNumber(LineNumber number) { number.accept(visitor); }
public void visitLocalVariableTable(LocalVariableTable table) {
table.accept(visitor);
LocalVariable[] vars = table.getLocalVariableTable();
for(int i=0; i < vars.length; i++)
vars[i].accept(this);
}
public void visitLocalVariable(LocalVariable var) { var.accept(visitor); }
public void visitConstantPool(ConstantPool cp) {
cp.accept(visitor);
Constant[] constants = cp.getConstantPool();
for(int i=1; i < constants.length; i++) {
if(constants[i] != null)
constants[i].accept(this);
}
}
public void visitConstantClass(ConstantClass constant) { constant.accept(visitor); }
public void visitConstantDouble(ConstantDouble constant) { constant.accept(visitor); }
public void visitConstantFieldref(ConstantFieldref constant) { constant.accept(visitor); }
public void visitConstantFloat(ConstantFloat constant) { constant.accept(visitor); }
public void visitConstantInteger(ConstantInteger constant) { constant.accept(visitor); }
public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref constant) {
constant.accept(visitor);
}
public void visitConstantLong(ConstantLong constant) { constant.accept(visitor); }
public void visitConstantMethodref(ConstantMethodref constant) {
constant.accept(visitor);
}
public void visitConstantNameAndType(ConstantNameAndType constant) {
constant.accept(visitor);
}
public void visitConstantString(ConstantString constant) { constant.accept(visitor); }
public void visitConstantUnicode(ConstantUnicode constant) { constant.accept(visitor); }
public void visitConstantUtf8(ConstantUtf8 constant) { constant.accept(visitor); }
public void visitInnerClasses(InnerClasses ic) {
ic.accept(visitor);
InnerClass[] ics = ic.getInnerClasses();
for(int i=0; i < ics.length; i++)
ics[i].accept(this);
}
public void visitInnerClass(InnerClass inner) { inner.accept(visitor); }
public void visitDeprecated(Deprecated attribute) { attribute.accept(visitor); }
public void visitSourceFile(SourceFile attribute) { attribute.accept(visitor); }
public void visitSynthetic(Synthetic attribute) { attribute.accept(visitor); }
public void visitUnknown(Unknown attribute) { attribute.accept(visitor); }
}
JavaClass/DE/fub/inf/JVM/JavaClass/ClassParser.java 100644 157 13 20565 6611373005 21174 0 ustar dahm institut package DE.fub.inf.JVM.JavaClass;
import DE.fub.inf.JVM.Constants;
import java.io.*;
import java.util.zip.*;
/**
* Wrapper class that parses a given Java .class file. The method
* parse returns a
*
* JavaClass object on success. When an I/O error or an
* inconsistency occurs an appropiate exception is propagated back
* to the caller.
*
* The structure and the names comply, except for a few conveniences,
* exactly with the
* JVM specification 1.0. See this paper for
* further details about the structure of a bytecode file.
*
* @version $Id: ClassParser.java,v 1.4 1998/10/15 13:17:57 dahm Exp $
* @author M. Dahm
*/
public final class ClassParser implements Constants {
private DataInputStream file;
private ZipFile zip;
private String file_name;
private int class_name_index, superclass_name_index;
private int major, minor; // Compiler version
private int access_flags; // Access rights of parsed class
private int[] interfaces; // Names of implemented interfaces
private ConstantPool constant_pool; // collection of constants
private Field[] fields; // class fields, i.e. its variables
private Method[] methods; // methods defined in the class
private Attribute[] attributes; // attributes defined in the class
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;
if(file instanceof DataInputStream) // Is already a data stream
this.file = (DataInputStream)file;
else
this.file = new DataInputStream(new BufferedInputStream(file, BUFSIZE));
}
/** Parse class from given .class file.
*
* @param file_name file name
* @throw IOException
*/
public ClassParser(String file_name) throws IOException
{
this.file_name = file_name;
file = new DataInputStream(new BufferedInputStream
(new FileInputStream(file_name), BUFSIZE));
}
/** Parse class from given .class file in a ZIP-archive
*
* @param file_name file name
* @throw IOException
*/
public ClassParser(String zip_file, String file_name) throws IOException
{
zip = new ZipFile(zip_file);
ZipEntry entry = zip.getEntry(file_name);
this.file_name = file_name;
file = new DataInputStream(new BufferedInputStream(zip.getInputStream(entry),
BUFSIZE));
}
/**
* Parse the given Java class file and return an object that represents
* the contained data, i.e. constants, methods, fields and commands.
* A ClassFormatError is raised, if the file is not a valid
* .class file. (This does not include verification of the byte code as it
* is performed by the java interpreter).
*
* @return Class object representing the parsed class file
* @throw IOException
* @throw ClassFormatError
*/
public JavaClass parse() throws IOException, ClassFormatError
{
/****************** 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);
System.err.println("WARNING: Trailing garbage at end of " + file_name);
System.err.println(bytes + " extra bytes: " + Utility.toHexString(buf));
}
// Read everything of interest, so close the file
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);
}
/**
* Read information about the attributes of the attributes of the class.
* @throw IOException
* @throw ClassFormatError
*/
private final void readAttributes() throws IOException, ClassFormatError
{
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);
}
/**
* Read information about the class and its super class.
* @throw IOException
* @throw ClassFormatError
*/
private final void readClassInfo() throws IOException, ClassFormatError
{
access_flags = file.readUnsignedShort();
/* Interfaces are implicitely abstract, the flag should be set
* according to the JVM specification.
*/
if((access_flags & ACC_INTERFACE) != 0)
access_flags |= ACC_ABSTRACT;
if(((access_flags & ACC_ABSTRACT) != 0) &&
((access_flags & ACC_FINAL) != 0 ))
throw new ClassFormatError("Class can't be both final and abstract");
class_name_index = file.readUnsignedShort();
superclass_name_index = file.readUnsignedShort();
}
/**
* Read constant pool entries.
* @throw IOException
* @throw ClassFormatError
*/
private final void readConstantPool() throws IOException, ClassFormatError
{
constant_pool = new ConstantPool(file);
}
/**
* Read information about the fields of the class, i.e. its variables.
* @throw IOException
* @throw ClassFormatError
*/
private final void readFields() throws IOException, ClassFormatError
{
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);
}
// No getXXX/setXXX methods, wouldn't make too much sense
/******************** 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.
* @throw IOException
* @throw ClassFormatError
*/
private final void readID() throws IOException, ClassFormatError
{
int magic = 0xCAFEBABE;
if(file.readInt() != magic)
throw new ClassFormatError(file_name + " is not a Java .class file");
}
/**
* Read information about the interfaces implemented by this class.
* @throw IOException
* @throw ClassFormatError
*/
private final void readInterfaces() throws IOException, ClassFormatError
{
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.
* @throw IOException
* @throw ClassFormatError
*/
private final void readMethods() throws IOException, ClassFormatError
{
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.
* @throw IOException
* @throw ClassFormatError
*/
private final void readVersion() throws IOException, ClassFormatError
{
minor = file.readUnsignedShort();
major = file.readUnsignedShort();
if((minor > MINOR) || (major > MAJOR))
throw new ClassFormatError("Incompatible version: " +
major + "." + minor);
}
}
JavaClass/DE/fub/inf/JVM/JavaClass/Attribute.class 100644 157 13 6710 6613636312 21062 0 ustar dahm institut - "DE/fub/inf/JVM/JavaClass/Attribute java/lang/Object DE/fub/inf/JVM/Constants java/lang/Cloneable
name_index I length tag B
constant_pool 'LDE/fub/inf/JVM/JavaClass/ConstantPool; accept %(LDE/fub/inf/JVM/JavaClass/Visitor;)V dump (Ljava/io/DataOutputStream;)V
Exceptions java/io/IOException Code LineNumberTable
java/io/DataOutputStream
writeShort (I)V
! writeInt #
$
readAttribute f(Ljava/io/DataInputStream;LDE/fub/inf/JVM/JavaClass/ConstantPool;)LDE/fub/inf/JVM/JavaClass/Attribute; java/lang/ClassFormatError ( java/lang/InternalError * java/io/DataInputStream , readUnsignedShort ()I . /
- 0 %DE/fub/inf/JVM/JavaClass/ConstantPool 2 getConstant '(IB)LDE/fub/inf/JVM/JavaClass/Constant; 4 5
3 6 %DE/fub/inf/JVM/JavaClass/ConstantUtf8 8 getBytes ()Ljava/lang/String; : ;
9 < readInt > /
- ? ATTRIBUTE_NAMES [Ljava/lang/String; A B C java/lang/String E equals (Ljava/lang/Object;)Z G H
F I DE/fub/inf/JVM/JavaClass/Unknown K E(IILjava/io/DataInputStream;LDE/fub/inf/JVM/JavaClass/ConstantPool;)V M N
L O &DE/fub/inf/JVM/JavaClass/ConstantValue Q M N
R S #DE/fub/inf/JVM/JavaClass/SourceFile U M N
V W DE/fub/inf/JVM/JavaClass/Code Y M N
Z [ 'DE/fub/inf/JVM/JavaClass/ExceptionTable ] M N
^ _ (DE/fub/inf/JVM/JavaClass/LineNumberTable a M N
b c +DE/fub/inf/JVM/JavaClass/LocalVariableTable e M N
f g %DE/fub/inf/JVM/JavaClass/InnerClasses i M N
j k "DE/fub/inf/JVM/JavaClass/Synthetic m M N
n o #DE/fub/inf/JVM/JavaClass/Deprecated q M N
r s !DE/fub/inf/JVM/JavaClass/PMGClass u M N
v w Ooops! default case reached. y (Ljava/lang/String;)V M {
+ | getLength setLength setNameIndex getNameIndex getTag ()B
getConstantPool )()LDE/fub/inf/JVM/JavaClass/ConstantPool; setConstantPool *(LDE/fub/inf/JVM/JavaClass/ConstantPool;)V clone ()Ljava/lang/Object;
java/lang/Throwable printStackTrace ()V
$java/lang/CloneNotSupportedException copy M(LDE/fub/inf/JVM/JavaClass/ConstantPool;)LDE/fub/inf/JVM/JavaClass/Attribute; toString -(BIILDE/fub/inf/JVM/JavaClass/ConstantPool;)V M
SourceFile Attribute.java!
1 +* +* " % : ; <