This commit was generated by cvs2svn to compensate for changes in r4,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
parent
af35ca5581
commit
ee13186158
148 changed files with 34934 additions and 0 deletions
111
src/FESI/ClassFile/Attribute.java
Normal file
111
src/FESI/ClassFile/Attribute.java
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
*
|
||||
* @(#) Attribute.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.Attribute
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
import FESI.ClassFile.UTF8Constant;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The Attribute class is an abstract base class for all Attribute types
|
||||
* found in the Java VM ClassFile format specification. This is a simple
|
||||
* implementationd designed to support the minimal functionaliuty required
|
||||
* to emit a valid ClassFile stream.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
abstract class Attribute {
|
||||
|
||||
final static String SOURCEFILE = "SourceFile";
|
||||
final static String CONSTANTVALUE = "ConstantValue";
|
||||
final static String LOCALVARIABLETABLE = "LocalVariableTable";
|
||||
final static String EXCEPTIONS = "Exceptions";
|
||||
final static String LINENUMBERTABLE = "LineNumberTable";
|
||||
final static String CODE = "Code";
|
||||
|
||||
private UTF8Constant name;
|
||||
private ClassFile classFile;
|
||||
|
||||
/**
|
||||
* <p> Construct an Attribute, enter it into the ConstantPool. </p>
|
||||
*/
|
||||
|
||||
protected Attribute(String n, ClassFile cf) {
|
||||
UTF8Constant utf8 = (UTF8Constant)
|
||||
cf.match(ConstantPoolEntry.CONSTANT_UTF8, (Object)n);
|
||||
|
||||
if (utf8 == null) utf8 = new UTF8Constant(n, cf);
|
||||
|
||||
name = utf8;
|
||||
classFile = cf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ClassFile this Attribute is contained within
|
||||
*/
|
||||
|
||||
ClassFile getClassFile() { return classFile; }
|
||||
|
||||
/**
|
||||
* @return the "name" of the Attribute.
|
||||
*/
|
||||
|
||||
String getName() { return name.getString(); }
|
||||
|
||||
/**
|
||||
* @return get the index of this Attribute in the ConstantPool
|
||||
*/
|
||||
|
||||
short getNameConstantPoolIndex() {
|
||||
return name.getConstantPoolIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the length of the attribute as defined by the concrete subclass.
|
||||
*/
|
||||
|
||||
abstract int getLength();
|
||||
|
||||
/**
|
||||
* <p> write the concrete Attribute subclass to the stream <p>
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
abstract void write(DataOutputStream dos) throws IOException;
|
||||
|
||||
/**
|
||||
* <p> Compare this Attribute with the object and return equality. </p>
|
||||
*
|
||||
* @return is it equal
|
||||
*/
|
||||
|
||||
abstract public boolean equals(Object o);
|
||||
|
||||
}
|
111
src/FESI/ClassFile/ClassConstant.java
Normal file
111
src/FESI/ClassFile/ClassConstant.java
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
*
|
||||
* @(#) ClassConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.ClassConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
import FESI.ClassFile.UTF8Constant;
|
||||
|
||||
class ClassConstant extends ConstantPoolEntry {
|
||||
|
||||
private UTF8Constant name;
|
||||
|
||||
/**
|
||||
* <p> Construct a CONSTANT_CLASS constant pool entry </p>
|
||||
*/
|
||||
|
||||
ClassConstant(String className, ClassFile cf) {
|
||||
super(CONSTANT_CLASS, cf);
|
||||
|
||||
name = cf.addUTF8Constant(ClassFile.fullyQualifiedForm(className));
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the CONSTANT_CLASS to the stream </p>
|
||||
*
|
||||
* @param dos the stream.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
|
||||
if (debug()) {
|
||||
System.err.println(getConstantPoolIndex() +
|
||||
" CLASS: " +
|
||||
name.getConstantPoolIndex()
|
||||
);
|
||||
}
|
||||
|
||||
dos.writeByte(getTag());
|
||||
dos.writeShort(name.getConstantPoolIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> return the class represented by the CONSTANT_CLASS </p>
|
||||
*
|
||||
* @return the name of the class
|
||||
*/
|
||||
|
||||
String getClassName() { return name.getString(); }
|
||||
|
||||
/**
|
||||
* <p> returns the Class object for the class represented by the constant. </p>
|
||||
*
|
||||
* @return The java.lang.Class object for the class.
|
||||
*/
|
||||
|
||||
Class getClassObject() throws ClassNotFoundException {
|
||||
return Class.forName(name.getString());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> compare the object, by name or value. </p>
|
||||
*
|
||||
* @param the object for comparison
|
||||
*
|
||||
* @return object equality.
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) return false;
|
||||
|
||||
if (o instanceof String) {
|
||||
return ((String)o).equals(name.getString());
|
||||
} else if (o instanceof ClassConstant) {
|
||||
ClassConstant cc = (ClassConstant)o;
|
||||
|
||||
return name.getString().equals(cc.getClassName());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
469
src/FESI/ClassFile/ClassFile.java
Normal file
469
src/FESI/ClassFile/ClassFile.java
Normal file
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
*
|
||||
* @(#) ClassFile.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.ClassFile
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import FESI.ClassFile.Attribute;
|
||||
import FESI.ClassFile.ClassConstant;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
import FESI.ClassFile.FieldDesc;
|
||||
import FESI.ClassFile.MethodDesc;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The ClassFile class is designed to provide lightweight, minimal support
|
||||
* for the runtime construction of Java VM ClassFile's, or Class
|
||||
* implementations.
|
||||
* </p>
|
||||
* <p>
|
||||
* The ClassFile provides API's to construct an in-core description of a
|
||||
* Java class implementation, and subsequently write that description to
|
||||
* a stream which may then be either loaded into the VM via a ClassLoader
|
||||
* or written to some persistent store.
|
||||
* </p>
|
||||
* <p>
|
||||
* It should be noted that the ClassFile provide little or no validation of
|
||||
* the Class it describes during the construction of that description, and
|
||||
* therefore users of this class and package should be familiar with the
|
||||
* contents of the Java VM Specification published by Addison-Wesley.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
final class ClassFile {
|
||||
|
||||
/**
|
||||
* <p> the magic number for Java VM class files. </p>
|
||||
*/
|
||||
|
||||
final private static int MAGIC = 0xcafebabe;
|
||||
|
||||
/**
|
||||
* <p> the major and minor version numbers for Java VM class files. </p>
|
||||
*/
|
||||
|
||||
final private static short MAJOR = 45;
|
||||
final private static short MINOR = 3;
|
||||
|
||||
/**
|
||||
* <p> the access flags constants for Java VM class files. </p>
|
||||
*/
|
||||
|
||||
final static short ACC_PUBLIC = 0x0001;
|
||||
final static short ACC_FINAL = 0x0010;
|
||||
final static short ACC_SUPER = 0x0020;
|
||||
final static short ACC_INTERFACE = 0x0200;
|
||||
final static short ACC_ABSTRACT = 0x0400;
|
||||
|
||||
/*
|
||||
* inst vars represent the format of the classfile itself.
|
||||
*/
|
||||
|
||||
private Vector constantPool = new Vector(1);
|
||||
|
||||
private short accessFlags = (short)(ACC_PUBLIC | ACC_SUPER);
|
||||
|
||||
private ClassConstant thisClass;
|
||||
private ClassConstant superClass;
|
||||
|
||||
private Vector interfaces;
|
||||
private Vector fields;
|
||||
private Vector methods;
|
||||
private Vector attributes;
|
||||
|
||||
/**
|
||||
* @return are we debuging (used to print audit trail).
|
||||
*/
|
||||
|
||||
static boolean debug() { return false; }
|
||||
|
||||
/**
|
||||
* <p> Construct a new ClassFile object. </p>
|
||||
*
|
||||
* @param tClass name of "this" class
|
||||
*
|
||||
* @param sClass name of superclass
|
||||
*
|
||||
*/
|
||||
|
||||
ClassFile(String tClass, String sClass) {
|
||||
thisClass = addClassConstant(tClass);
|
||||
superClass = addClassConstant(sClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Write the constant pool to the stream </p>
|
||||
*
|
||||
* @param dos the stream to write to.
|
||||
*/
|
||||
|
||||
private void writeConstantPool(DataOutputStream dos) throws IOException {
|
||||
|
||||
if (debug()) System.err.println("write constant pool: " + constantPool.size());
|
||||
|
||||
dos.writeShort(constantPool.size() + 1); // for index zero
|
||||
|
||||
for (int i = 0; i < constantPool.size(); i++) {
|
||||
((ConstantPoolEntry)constantPool.elementAt(i)).write(dos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Write the list of interfaces to the stream </p>
|
||||
*
|
||||
* @param dos the stream to write to.
|
||||
*/
|
||||
|
||||
private void writeInterfaces(DataOutputStream dos) throws IOException {
|
||||
if (interfaces != null) {
|
||||
if (debug()) System.err.println("write interfaces: " + interfaces.size());
|
||||
dos.writeShort(interfaces.size());
|
||||
|
||||
for (int i = 0; i < interfaces.size(); i++) {
|
||||
dos.writeShort(
|
||||
((ConstantPoolEntry)interfaces.elementAt(i)).getConstantPoolIndex()
|
||||
);
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Write the list of Fields defs to the stream </p>
|
||||
*
|
||||
* @param dos the stream to write to.
|
||||
*/
|
||||
|
||||
private void writeFields(DataOutputStream dos) throws IOException {
|
||||
if (fields != null) {
|
||||
if (debug()) System.err.println("write fields: " + fields.size());
|
||||
|
||||
dos.writeShort(fields.size());
|
||||
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
((FieldDesc)fields.elementAt(i)).write(dos);
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Write the list of Method defs to the stream. </p>
|
||||
*
|
||||
* @param dos the stream to write to.
|
||||
*/
|
||||
|
||||
private void writeMethods(DataOutputStream dos) throws IOException {
|
||||
if (methods != null) {
|
||||
if (debug()) System.err.println("write methods: " + methods.size());
|
||||
|
||||
dos.writeShort(methods.size());
|
||||
|
||||
for (int i = 0; i < methods.size(); i++) {
|
||||
((MethodDesc)methods.elementAt(i)).write(dos);
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Write the list of Attributes to the stream </p>
|
||||
*
|
||||
* @param dos the stream to write to.
|
||||
*/
|
||||
|
||||
private void writeAttributes(DataOutputStream dos) throws IOException {
|
||||
if (attributes != null) {
|
||||
if (debug()) System.err.println("write attributes: " + attributes.size());
|
||||
|
||||
dos.writeShort(attributes.size());
|
||||
|
||||
for (int i = 0; i < attributes.size(); i++) {
|
||||
((Attribute)attributes.elementAt(i)).write(dos);
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Write the ClassFile to the Stream </p>
|
||||
*
|
||||
* @param os the stream to write to.
|
||||
*/
|
||||
|
||||
public synchronized void write(OutputStream os) throws IOException {
|
||||
DataOutputStream dos = new DataOutputStream(os);
|
||||
|
||||
try {
|
||||
dos.writeInt(MAGIC);
|
||||
|
||||
dos.writeShort(MINOR);
|
||||
dos.writeShort(MAJOR);
|
||||
|
||||
writeConstantPool(dos);
|
||||
|
||||
if (debug()) System.err.println("access: " + accessFlags);
|
||||
|
||||
dos.writeShort(accessFlags);
|
||||
|
||||
dos.writeShort(thisClass.getConstantPoolIndex());
|
||||
dos.writeShort(superClass.getConstantPoolIndex());
|
||||
|
||||
writeInterfaces(dos);
|
||||
|
||||
writeFields(dos);
|
||||
|
||||
writeMethods(dos);
|
||||
|
||||
writeAttributes(dos);
|
||||
|
||||
dos.close(); // all done!
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("Bad IO");
|
||||
} catch (Exception e) {
|
||||
System.err.println("Oops");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Add an entry to the Constant Pool. </p>
|
||||
*
|
||||
* @param cpe the new constant pool entry
|
||||
*
|
||||
* @return the index of the new entry in the pool
|
||||
*/
|
||||
|
||||
public synchronized short addConstantPoolEntry(ConstantPoolEntry cpe) {
|
||||
if (!constantPool.contains(cpe)) constantPool.addElement(cpe);
|
||||
|
||||
return (short)(constantPool.indexOf(cpe) + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Find a matching Constant Pool Entry. </p>
|
||||
*
|
||||
* @param tag The tag value of the constant pool entries to match on.
|
||||
* @param value The value to match on.
|
||||
*
|
||||
* @return the matching entry or null.
|
||||
*/
|
||||
|
||||
synchronized ConstantPoolEntry match(byte tag, Object value) {
|
||||
for (int i = 0; i < constantPool.size(); i++) {
|
||||
ConstantPoolEntry cpe = (ConstantPoolEntry)constantPool.elementAt(i);
|
||||
|
||||
if (cpe.getTag() == tag && cpe.equals(value))
|
||||
return cpe;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current value of the accessFlags.
|
||||
*/
|
||||
|
||||
public synchronized short getAccessFlags() { return accessFlags; }
|
||||
|
||||
/**
|
||||
* <p> modify the value of the Class File's access flags </p>
|
||||
*
|
||||
* @param newf the new flag values. [NOT VALIDATED]
|
||||
*/
|
||||
|
||||
public synchronized void setAccessFlags(short newf) {
|
||||
|
||||
// TODO - verify new flag combination.
|
||||
|
||||
accessFlags = newf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newMethod the method desc to add to the class file.
|
||||
*/
|
||||
|
||||
public synchronized void addMethodDesc(MethodDesc newMethod) {
|
||||
if (methods == null) methods = new Vector(1);
|
||||
|
||||
methods.addElement(newMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newField the field desc to add to the class file.
|
||||
*/
|
||||
|
||||
public synchronized void addFieldDesc(FieldDesc newField) {
|
||||
if (fields == null) fields = new Vector(1);
|
||||
|
||||
fields.addElement(newField);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sConstant add a CONSTANT_STRING to the ClassFile.
|
||||
*
|
||||
* @param sConstant the string value to add.
|
||||
*
|
||||
* @return The new StringConstant
|
||||
*/
|
||||
|
||||
public StringConstant addStringConstant(String sConstant) {
|
||||
UTF8Constant c = (UTF8Constant)match(ConstantPoolEntry.CONSTANT_UTF8, sConstant);
|
||||
|
||||
if (c == null) {
|
||||
c = new UTF8Constant(sConstant, this);
|
||||
}
|
||||
|
||||
StringConstant s = new StringConstant(c, this);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Add a new CONSTANT_INTEGER to the Constant Pool </p>
|
||||
*
|
||||
* @param iConstant the integer value to add.
|
||||
*
|
||||
* @return the new IntegerConstant.
|
||||
*/
|
||||
|
||||
public IntegerConstant addIntegerConstant(int iConstant) {
|
||||
IntegerConstant c = (IntegerConstant)match(ConstantPoolEntry.CONSTANT_INTEGER, new Integer(iConstant));
|
||||
|
||||
if (c == null) {
|
||||
c = new IntegerConstant(iConstant, this);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Add a new UTF8_CONSTANT to the constant pool </p>
|
||||
*
|
||||
* @param sConstant the string to add.
|
||||
*
|
||||
* @return the new UUTF8Constant
|
||||
*/
|
||||
|
||||
public UTF8Constant addUTF8Constant(String sConstant) {
|
||||
UTF8Constant c = (UTF8Constant)match(ConstantPoolEntry.CONSTANT_UTF8, sConstant);
|
||||
|
||||
if (c == null) {
|
||||
c = new UTF8Constant(sConstant, this);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add a new CONSTANT_CLASS to the Constant Pool </p>
|
||||
*
|
||||
* @param classConstant the name of the class to add
|
||||
*
|
||||
* @return the newly ClassConstant
|
||||
*/
|
||||
|
||||
public ClassConstant addClassConstant(String classConstant) {
|
||||
ClassConstant c = (ClassConstant)match(ConstantPoolEntry.CONSTANT_CLASS, classConstant);
|
||||
|
||||
if (c == null) {
|
||||
c = new ClassConstant(classConstant, this);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add a CONSTANT_METHOD to the constant pool </p>
|
||||
*
|
||||
* @param cName the name of the defining class
|
||||
* @param mName the method name
|
||||
* @param tName the fully qualified type descriptor for the method
|
||||
*
|
||||
* @return the new created CONSTANT_METHOD
|
||||
*/
|
||||
|
||||
public MethodConstant addMethodConstant(String cName, String mName, String tName) {
|
||||
return new MethodConstant(cName, mName, tName, this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param cName the name of the defining class
|
||||
* @param fName the name of the field
|
||||
* @param tName the fully qualified type descriptor of the field
|
||||
*
|
||||
* @return the new created CONSTANT_FIELD
|
||||
*/
|
||||
|
||||
public FieldConstant addFieldConstant(String cName, String fName, String tName) {
|
||||
return new FieldConstant(cName, fName, tName, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add the name of an interface this class implements to the constant pool </p>
|
||||
*
|
||||
* @param iName the name of the interface
|
||||
*/
|
||||
|
||||
public void addInterface(String iName) {
|
||||
if (interfaces == null) interfaces = new Vector(1);
|
||||
|
||||
interfaces.addElement((Object)addClassConstant(iName));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* convenience routine to take a type name and map it to the internal form.
|
||||
* java.lang.Object -> java/lang/Object
|
||||
* </p>
|
||||
*
|
||||
* @param str the string to map
|
||||
*
|
||||
* @return the mapped string value.
|
||||
*/
|
||||
|
||||
public static String fullyQualifiedForm(String str) {
|
||||
return str.replace('.', '/');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* convenience routine to construct type descriptors from fully
|
||||
* qualified names, e.g: java.lang.Object => Ljava/lang/Object;
|
||||
* </p>
|
||||
*
|
||||
* @param str name of a java "type"
|
||||
*
|
||||
* @return the class descriptor.
|
||||
*/
|
||||
|
||||
public static String fieldType(String str) {
|
||||
return "L" + ClassFile.fullyQualifiedForm(str) + ";";
|
||||
}
|
||||
|
||||
}
|
702
src/FESI/ClassFile/Code.java
Normal file
702
src/FESI/ClassFile/Code.java
Normal file
|
@ -0,0 +1,702 @@
|
|||
/*
|
||||
*
|
||||
* @(#) Code.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.Code
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import FESI.ClassFile.Attribute;
|
||||
import FESI.ClassFile.ClassConstant;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The Code attribute is defined to describe the implementation for each
|
||||
* Method Implementation in a class. In particular it contains the byte
|
||||
* codes and exception information.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
final class Code extends Attribute {
|
||||
|
||||
final static byte OP_NOP = (byte) 0x00;
|
||||
final static byte OP_ACONST_NULL = (byte) 0x01;
|
||||
|
||||
// int consts
|
||||
|
||||
final static byte OP_ICONST_m1 = (byte) 0x02;
|
||||
final static byte OP_ICONST_0 = (byte) 0x03;
|
||||
final static byte OP_ICONST_1 = (byte) 0x04;
|
||||
final static byte OP_ICONST_2 = (byte) 0x05;
|
||||
final static byte OP_ICONST_3 = (byte) 0x06;
|
||||
final static byte OP_ICONST_4 = (byte) 0x07;
|
||||
final static byte OP_ICONST_5 = (byte) 0x08;
|
||||
|
||||
// long consts
|
||||
|
||||
final static byte OP_LCONST_0 = (byte) 0x09;
|
||||
final static byte OP_LCONST_1 = (byte) 0x0A;
|
||||
|
||||
// float consts
|
||||
|
||||
final static byte OP_FCONST_0 = (byte) 0x0B;
|
||||
final static byte OP_FCONST_1 = (byte) 0x0C;
|
||||
final static byte OP_FCONST_2 = (byte) 0x0D;
|
||||
|
||||
// double consts
|
||||
|
||||
final static byte OP_DCONST_0 = (byte) 0x0E;
|
||||
final static byte OP_DCONST_1 = (byte) 0x0F;
|
||||
|
||||
final static byte OP_BIPUSH = (byte) 0x10;
|
||||
final static byte OP_SIPUSH = (byte) 0x11;
|
||||
|
||||
final static byte OP_LDC = (byte) 0x12;
|
||||
final static byte OP_LDC_WIDE = (byte) 0x13;
|
||||
final static byte OP_LDC2_WIDE = (byte) 0x14;
|
||||
|
||||
|
||||
// typed loads local
|
||||
|
||||
final static byte OP_ILOAD = (byte) 0x15;
|
||||
final static byte OP_LLOAD = (byte) 0x16;
|
||||
final static byte OP_FLOAD = (byte) 0x17;
|
||||
final static byte OP_DLOAD = (byte) 0x18;
|
||||
final static byte OP_ALOAD = (byte) 0x19;
|
||||
|
||||
// int loads
|
||||
|
||||
final static byte OP_ILOAD_0 = (byte) 0x1A;
|
||||
final static byte OP_ILOAD_1 = (byte) 0x1B;
|
||||
final static byte OP_ILOAD_2 = (byte) 0x1C;
|
||||
final static byte OP_ILOAD_3 = (byte) 0x1D;
|
||||
|
||||
// long loads
|
||||
|
||||
final static byte OP_LLOAD_0 = (byte) 0x1E;
|
||||
final static byte OP_LLOAD_1 = (byte) 0x1F;
|
||||
final static byte OP_LLOAD_2 = (byte) 0x20;
|
||||
final static byte OP_LLOAD_3 = (byte) 0x21;
|
||||
|
||||
// float loads
|
||||
|
||||
final static byte OP_FLOAD_0 = (byte) 0x22;
|
||||
final static byte OP_FLOAD_1 = (byte) 0x23;
|
||||
final static byte OP_FLOAD_2 = (byte) 0x24;
|
||||
final static byte OP_FLOAD_3 = (byte) 0x25;
|
||||
|
||||
// double loads
|
||||
|
||||
final static byte OP_DLOAD_0 = (byte) 0x26;
|
||||
final static byte OP_DLOAD_1 = (byte) 0x27;
|
||||
final static byte OP_DLOAD_2 = (byte) 0x28;
|
||||
final static byte OP_DLOAD_3 = (byte) 0x29;
|
||||
|
||||
// ref loads
|
||||
|
||||
final static byte OP_ALOAD_0 = (byte) 0x2A;
|
||||
final static byte OP_ALOAD_1 = (byte) 0x2B;
|
||||
final static byte OP_ALOAD_2 = (byte) 0x2C;
|
||||
final static byte OP_ALOAD_3 = (byte) 0x2D;
|
||||
|
||||
final static byte OP_IALOAD = (byte) 0x2E;
|
||||
final static byte OP_LALOAD = (byte) 0x2F;
|
||||
|
||||
// array loads
|
||||
|
||||
final static byte OP_FALOAD = (byte) 0x30;
|
||||
final static byte OP_DALOAD = (byte) 0x31;
|
||||
final static byte OP_AALOAD = (byte) 0x32;
|
||||
final static byte OP_BALOAD = (byte) 0x33;
|
||||
final static byte OP_CALOAD = (byte) 0x34;
|
||||
final static byte OP_SALOAD = (byte) 0x35;
|
||||
|
||||
final static byte OP_ISTORE = (byte) 0x36;
|
||||
final static byte OP_LSTORE = (byte) 0x37;
|
||||
final static byte OP_FSTORE = (byte) 0x38;
|
||||
final static byte OP_DSTORE = (byte) 0x39;
|
||||
final static byte OP_ASTORE = (byte) 0x3A;
|
||||
|
||||
// int stores
|
||||
|
||||
final static byte OP_ISTORE_0 = (byte) 0x3B;
|
||||
final static byte OP_ISTORE_1 = (byte) 0x3C;
|
||||
final static byte OP_ISTORE_2 = (byte) 0x3D;
|
||||
final static byte OP_ISTORE_3 = (byte) 0x3E;
|
||||
|
||||
// long stores
|
||||
|
||||
final static byte OP_LSTORE_0 = (byte) 0x3F;
|
||||
final static byte OP_LSTORE_1 = (byte) 0x40;
|
||||
final static byte OP_LSTORE_2 = (byte) 0x41;
|
||||
final static byte OP_LSTORE_3 = (byte) 0x42;
|
||||
|
||||
// float stores
|
||||
|
||||
final static byte OP_FSTORE_0 = (byte) 0x43;
|
||||
final static byte OP_FSTORE_1 = (byte) 0x44;
|
||||
final static byte OP_FSTORE_2 = (byte) 0x45;
|
||||
final static byte OP_FSTORE_3 = (byte) 0x46;
|
||||
|
||||
// double stores
|
||||
|
||||
final static byte OP_DSTORE_0 = (byte) 0x47;
|
||||
final static byte OP_DSTORE_1 = (byte) 0x48;
|
||||
final static byte OP_DSTORE_2 = (byte) 0x49;
|
||||
final static byte OP_DSTORE_3 = (byte) 0x4A;
|
||||
|
||||
// ref stores
|
||||
|
||||
final static byte OP_ASTORE_0 = (byte) 0x4B;
|
||||
final static byte OP_ASTORE_1 = (byte) 0x4C;
|
||||
final static byte OP_ASTORE_2 = (byte) 0x4D;
|
||||
final static byte OP_ASTORE_3 = (byte) 0x4E;
|
||||
|
||||
final static byte OP_IASTORE = (byte) 0x4F;
|
||||
|
||||
// array stores
|
||||
|
||||
final static byte OP_LASTORE = (byte) 0x50;
|
||||
final static byte OP_FASTORE = (byte) 0x51;
|
||||
final static byte OP_DASTORE = (byte) 0x52;
|
||||
final static byte OP_AASTORE = (byte) 0x53;
|
||||
final static byte OP_BASTORE = (byte) 0x54;
|
||||
final static byte OP_CASTORE = (byte) 0x55;
|
||||
final static byte OP_SASTORE = (byte) 0x56;
|
||||
|
||||
final static byte OP_POP = (byte) 0x57;
|
||||
final static byte OP_POP2 = (byte) 0x58;
|
||||
|
||||
// dup's
|
||||
|
||||
final static byte OP_DUP = (byte) 0x59;
|
||||
final static byte OP_DUP_X1 = (byte) 0x5A;
|
||||
final static byte OP_DUP_X2 = (byte) 0x5B;
|
||||
final static byte OP_DUP2 = (byte) 0x5C;
|
||||
final static byte OP_DUP2_X1 = (byte) 0x5D;
|
||||
final static byte OP_DUP2_X2 = (byte) 0x5E;
|
||||
final static byte OP_SWAP = (byte) 0x5F;
|
||||
|
||||
// arith
|
||||
|
||||
final static byte OP_IADD = (byte) 0x60;
|
||||
final static byte OP_LADD = (byte) 0x61;
|
||||
final static byte OP_FADD = (byte) 0x62;
|
||||
final static byte OP_DADD = (byte) 0x63;
|
||||
|
||||
final static byte OP_ISUB = (byte) 0x64;
|
||||
final static byte OP_LSUB = (byte) 0x65;
|
||||
final static byte OP_FSUB = (byte) 0x66;
|
||||
final static byte OP_DSUB = (byte) 0x67;
|
||||
|
||||
final static byte OP_IMUL = (byte) 0x68;
|
||||
final static byte OP_LMUL = (byte) 0x69;
|
||||
final static byte OP_FMUL = (byte) 0x6A;
|
||||
final static byte OP_DMUL = (byte) 0x6B;
|
||||
|
||||
final static byte OP_IDIV = (byte) 0x6C;
|
||||
final static byte OP_FDIV = (byte) 0x6E;
|
||||
final static byte OP_LDIV = (byte) 0x6D;
|
||||
final static byte OP_DDIV = (byte) 0x6F;
|
||||
|
||||
// arith misc
|
||||
|
||||
final static byte OP_IREM = (byte) 0x70;
|
||||
final static byte OP_LREM = (byte) 0x71;
|
||||
final static byte OP_FREM = (byte) 0x72;
|
||||
final static byte OP_DREM = (byte) 0x73;
|
||||
|
||||
final static byte OP_INEG = (byte) 0x74;
|
||||
final static byte OP_LNEG = (byte) 0x75;
|
||||
final static byte OP_FNEG = (byte) 0x76;
|
||||
final static byte OP_DNEG = (byte) 0x77;
|
||||
|
||||
final static byte OP_ISHL = (byte) 0x78;
|
||||
final static byte OP_LSHL = (byte) 0x79;
|
||||
|
||||
final static byte OP_ISHR = (byte) 0x7A;
|
||||
final static byte OP_LSHR = (byte) 0x7B;
|
||||
|
||||
final static byte OP_IUSHR = (byte) 0x7C;
|
||||
final static byte OP_LUSHR = (byte) 0x7D;
|
||||
|
||||
final static byte OP_IAND = (byte) 0x7E;
|
||||
final static byte OP_LAND = (byte) 0x7F;
|
||||
|
||||
final static byte OP_IOR = (byte) 0x80;
|
||||
final static byte OP_LOR = (byte) 0x81;
|
||||
|
||||
final static byte OP_IXOR = (byte) 0x82;
|
||||
final static byte OP_LXOR = (byte) 0x83;
|
||||
|
||||
// local int += const
|
||||
|
||||
final static byte OP_IINC = (byte) 0x84;
|
||||
|
||||
// int conversions
|
||||
|
||||
final static byte OP_I2L = (byte) 0x85;
|
||||
final static byte OP_I2F = (byte) 0x86;
|
||||
final static byte OP_I2D = (byte) 0x87;
|
||||
|
||||
// long conversions
|
||||
|
||||
final static byte OP_L2I = (byte) 0x88;
|
||||
final static byte OP_L2F = (byte) 0x89;
|
||||
final static byte OP_L2D = (byte) 0x8A;
|
||||
|
||||
// float conversions
|
||||
|
||||
final static byte OP_F2I = (byte) 0x8B;
|
||||
final static byte OP_F2L = (byte) 0x8C;
|
||||
final static byte OP_F2D = (byte) 0x8D;
|
||||
|
||||
// double conversions
|
||||
|
||||
final static byte OP_D2I = (byte) 0x8E;
|
||||
final static byte OP_D2L = (byte) 0x8F;
|
||||
final static byte OP_D2F = (byte) 0x90;
|
||||
|
||||
// int conversions
|
||||
|
||||
final static byte OP_I2B = (byte) 0x91;
|
||||
final static byte OP_I2C = (byte) 0x92;
|
||||
final static byte OP_I2S = (byte) 0x93;
|
||||
|
||||
// long comparision's
|
||||
|
||||
final static byte OP_LCMP = (byte) 0x94;
|
||||
|
||||
// float comparision's
|
||||
|
||||
final static byte OP_FCMPL = (byte) 0x95;
|
||||
final static byte OP_FCMPG = (byte) 0x96;
|
||||
|
||||
// double comparision's
|
||||
|
||||
final static byte OP_DCMPL = (byte) 0x97;
|
||||
final static byte OP_DCMPG = (byte) 0x98;
|
||||
|
||||
// int to zero comparisions
|
||||
|
||||
final static byte OP_IFEQ = (byte) 0x99;
|
||||
final static byte OP_IFNE = (byte) 0x9A;
|
||||
final static byte OP_IFLT = (byte) 0x9B;
|
||||
final static byte OP_IFGE = (byte) 0x9C;
|
||||
final static byte OP_IFGT = (byte) 0x9D;
|
||||
final static byte OP_IFLE = (byte) 0x9E;
|
||||
|
||||
// int to int comparision's
|
||||
|
||||
final static byte OP_IFICMPEQ = (byte) 0x9F;
|
||||
final static byte OP_IFICMPNE = (byte) 0xA0;
|
||||
final static byte OP_IFICMPLT = (byte) 0xA1;
|
||||
final static byte OP_IFICMPGE = (byte) 0xA2;
|
||||
final static byte OP_IFICMPGT = (byte) 0xA3;
|
||||
final static byte OP_IFICMPLE = (byte) 0xA4;
|
||||
|
||||
// ref comparisions
|
||||
|
||||
final static byte OP_IFACMPEQ = (byte) 0xA5;
|
||||
final static byte OP_IFACMPNE = (byte) 0xA6;
|
||||
|
||||
// goto
|
||||
|
||||
final static byte OP_GOTO = (byte) 0xA7;
|
||||
|
||||
final static byte OP_JSR = (byte) 0xA8;
|
||||
|
||||
final static byte OP_RET = (byte) 0xA9;
|
||||
|
||||
final static byte OP_TABLESWITCH = (byte) 0xAA;
|
||||
|
||||
final static byte OP_LOOKUP_SWITCH = (byte) 0xAB;
|
||||
|
||||
|
||||
// return's
|
||||
|
||||
final static byte OP_IRETURN = (byte) 0xAC;
|
||||
final static byte OP_LRETURN = (byte) 0xAD;
|
||||
final static byte OP_FRETURN = (byte) 0xAE;
|
||||
final static byte OP_DRETURN = (byte) 0xAF;
|
||||
final static byte OP_ARETURN = (byte) 0xB0;
|
||||
final static byte OP_RETURN = (byte) 0xB1;
|
||||
|
||||
|
||||
// getfield's
|
||||
|
||||
final static byte OP_GETSTATIC = (byte) 0xB2;
|
||||
final static byte OP_GETFIELD = (byte) 0xB4;
|
||||
|
||||
// invoke virtual
|
||||
|
||||
final static byte OP_INVOKE_VIRTUAL = (byte) 0xB6;
|
||||
|
||||
// invoke static
|
||||
|
||||
final static byte OP_INVOKE_STATIC = (byte) 0xB8;
|
||||
|
||||
// method invocation
|
||||
|
||||
final static byte OP_INVOKE_SPECIAL = (byte) 0xB7;
|
||||
|
||||
// invoke interface
|
||||
|
||||
final static byte OP_INVOKE_INTERFACE = (byte) 0xB9;
|
||||
|
||||
// new
|
||||
|
||||
final static byte OP_NEW = (byte) 0xBB;
|
||||
|
||||
// array misc
|
||||
|
||||
final static byte OP_NEWARRAY = (byte) 0xBD;
|
||||
|
||||
final static byte ARRAY_T_BOOLEAN = (byte) 0x4;
|
||||
final static byte ARRAY_T_CHAR = (byte) 0x5;
|
||||
final static byte ARRAY_T_FLOAT = (byte) 0x6;
|
||||
final static byte ARRAY_T_DOUBLE = (byte) 0x7;
|
||||
final static byte ARRAY_T_BYTE = (byte) 0x8;
|
||||
final static byte ARRAY_T_SHORT = (byte) 0x9;
|
||||
final static byte ARRAY_T_INT = (byte) 0xA;
|
||||
final static byte ARRAY_T_LONG = (byte) 0xB;
|
||||
|
||||
// putfield's
|
||||
|
||||
final static byte OP_PUTSTATIC = (byte) 0xB3;
|
||||
final static byte OP_PUTFIELD = (byte) 0xB5;
|
||||
|
||||
// array's
|
||||
|
||||
final static byte OP_ANEWARRAY = (byte) 0xBD;
|
||||
final static byte OP_ARRAYLENGTH = (byte) 0xBE;
|
||||
|
||||
// exceptions
|
||||
|
||||
final static byte OP_ATHROW = (byte) 0xBF;
|
||||
|
||||
// cast
|
||||
|
||||
final static byte OP_CHECKCAST = (byte) 0xC0;
|
||||
|
||||
// instanceof
|
||||
|
||||
final static byte OP_INSTANCEOF = (byte) 0xC1;
|
||||
|
||||
// monitor
|
||||
|
||||
final static byte OP_MONITOR_ENTER = (byte) 0xC2;
|
||||
final static byte OP_MONITOR_EXIT = (byte) 0xC3;
|
||||
|
||||
// wide
|
||||
|
||||
final static byte OP_WIDE = (byte) 0xC4;
|
||||
|
||||
// arrays
|
||||
|
||||
final static byte OP_MULTI_NEW_ARRAY = (byte) 0xC5;
|
||||
|
||||
// compare to null
|
||||
|
||||
final static byte OP_IFNULL = (byte) 0xc6;
|
||||
final static byte OP_IFNONNULL = (byte) 0xc7;
|
||||
|
||||
// goto wide
|
||||
|
||||
final static byte OP_GOTO_WIDE = (byte) 0xc8;
|
||||
|
||||
final static byte OP_JSR_WIDE = (byte) 0xc9;
|
||||
|
||||
|
||||
/*
|
||||
* inst vars
|
||||
*/
|
||||
|
||||
private Vector attributes;
|
||||
|
||||
private int length = 12; // starting value
|
||||
|
||||
private short currentPC;
|
||||
|
||||
private short maxLocals;
|
||||
|
||||
private short maxStack;
|
||||
|
||||
private Vector byteCodes = new Vector(1);
|
||||
|
||||
private Vector exceptions;
|
||||
|
||||
/**
|
||||
* <p> construct a Code Attribute </p>
|
||||
*
|
||||
* @param locals number of words used to describe local vars
|
||||
* @param maxstack max number of stack words used.
|
||||
*
|
||||
*/
|
||||
|
||||
Code(ClassFile cf, short locals, short stack) {
|
||||
super(CODE, cf);
|
||||
|
||||
maxLocals = (locals >= 0 ? locals : 0);
|
||||
maxStack = (stack > 2 ? stack : 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the code attribute to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
int i;
|
||||
|
||||
dos.writeShort(getNameConstantPoolIndex());
|
||||
dos.writeInt(getLength());
|
||||
dos.writeShort(maxStack);
|
||||
dos.writeShort(maxLocals);
|
||||
|
||||
// write the code ...
|
||||
|
||||
dos.writeInt(byteCodes.size());
|
||||
|
||||
for (i = 0; i < byteCodes.size(); i++) {
|
||||
dos.writeByte(((Byte)byteCodes.elementAt(i)).byteValue());
|
||||
}
|
||||
|
||||
// write exceptions (if any)
|
||||
|
||||
if (exceptions != null) {
|
||||
dos.writeShort(exceptions.size());
|
||||
|
||||
for (i = 0; i < exceptions.size(); i++) {
|
||||
((ExceptionTableEntry)exceptions.elementAt(i)).write(dos);
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
|
||||
// write attributes (if any)
|
||||
|
||||
if (attributes != null) {
|
||||
dos.writeShort(attributes.size());
|
||||
|
||||
for (i = 0; i < attributes.size(); i ++) {
|
||||
((Attribute)attributes.elementAt(i)).write(dos);
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> returns the length of the Code attribute in bytes </p>
|
||||
*
|
||||
* @return the length of the attribute.
|
||||
*/
|
||||
|
||||
int getLength() { return length; }
|
||||
|
||||
/**
|
||||
* @return object equality.
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return ((Object)this).equals(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current PC offset from the start of the method.
|
||||
*/
|
||||
|
||||
short getCurrentPC() { return currentPC; }
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* adds per Code attribute, can be used for SourceFile, LocalVariable,
|
||||
* and LineNumberTable attributes etc.
|
||||
* </p>
|
||||
*
|
||||
* @param attr Attribte to be added.
|
||||
*/
|
||||
|
||||
void addAttribute(Attribute attr) {
|
||||
if (attributes == null) attributes = new Vector(1);
|
||||
|
||||
attributes.addElement(attr);
|
||||
length += attr.getLength() + 6; // sizeof(Attribute)
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Adds an entry to the Exception handler table for this Code attribute.
|
||||
* An entry describes the start and stop pc offset within the Code fragment
|
||||
* for which an exception handler is provided, the start pc of the handler
|
||||
* code within the fragment itself, and the class of the exception type
|
||||
* for this handler.
|
||||
* </p>
|
||||
*
|
||||
* @param start start pc offset for this exception handler range
|
||||
* @param stop stop pc offset for this exception handler range
|
||||
* @param handler handler pc start offset for this exception
|
||||
* @param ct CONSTANT_CLASS describing the exception class handled
|
||||
*/
|
||||
|
||||
void addExceptionTableEntry(short start, short stop,
|
||||
short handler, ClassConstant ct) {
|
||||
exceptions.addElement(
|
||||
new ExceptionTableEntry(start, stop, handler, ct)
|
||||
);
|
||||
|
||||
length += 8; // sizeof(ExceptionTableEntry)
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add an opcode to the implementation </p>
|
||||
*/
|
||||
|
||||
void addOp(byte opCode) {
|
||||
byteCodes.addElement(new Byte(opCode));
|
||||
currentPC++;
|
||||
length++;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add an opcode and a 1 byte operand </p>
|
||||
*/
|
||||
|
||||
void addOp1(byte opCode, byte op1) {
|
||||
byteCodes.addElement(new Byte(opCode));
|
||||
byteCodes.addElement(new Byte(op1));
|
||||
currentPC += 2;
|
||||
length += 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add an opcode and 2, 1 byte operands </p>
|
||||
*/
|
||||
|
||||
void addOp2(byte opCode, byte op1, byte op2) {
|
||||
byteCodes.addElement(new Byte(opCode));
|
||||
byteCodes.addElement(new Byte(op1));
|
||||
byteCodes.addElement(new Byte(op2));
|
||||
currentPC += 3;
|
||||
length += 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add an opcode and 4, 1 byte operands </p>
|
||||
*/
|
||||
|
||||
void addOp4(byte opCode, byte op1, byte op2, byte op3, byte op4) {
|
||||
byteCodes.addElement(new Byte(opCode));
|
||||
byteCodes.addElement(new Byte(op1));
|
||||
byteCodes.addElement(new Byte(op2));
|
||||
byteCodes.addElement(new Byte(op3));
|
||||
byteCodes.addElement(new Byte(op4));
|
||||
currentPC += 5;
|
||||
length += 5;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add an opcode and a 2 byte operand </p>
|
||||
*/
|
||||
|
||||
void addOpShort(byte opCode,short op) {
|
||||
addOp2(opCode,
|
||||
(byte)((op >>> 8) & 0xff),
|
||||
(byte)( op & 0xff)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> add an opcode and a 4 byte operand </p>
|
||||
*/
|
||||
|
||||
void addOpInt(byte opCode,int op) {
|
||||
addOp4(opCode,
|
||||
(byte)((op >>> 24) & 0xff),
|
||||
(byte)((op >>> 16) & 0xff),
|
||||
(byte)((op >>> 8) & 0xff),
|
||||
(byte)( op & 0xff)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> increment the local word count </p>
|
||||
*
|
||||
* @param n the number of local words to increment by.
|
||||
*/
|
||||
|
||||
void incrLocals(short n) { maxLocals += n; }
|
||||
|
||||
/**
|
||||
* <p> increment the max operand stack word count </p>
|
||||
*
|
||||
* @param n the number of words to increment the max stack count by
|
||||
*/
|
||||
|
||||
void incrMaxStack(short n) { maxStack += n; }
|
||||
}
|
||||
|
||||
/*
|
||||
* private implementation class to represent exception table entries.
|
||||
*/
|
||||
|
||||
final class ExceptionTableEntry {
|
||||
private short startPC;
|
||||
private short stopPC;
|
||||
private short handlerPC;
|
||||
private ClassConstant exceptionType;
|
||||
|
||||
/*
|
||||
* construct and Exception Table Entry
|
||||
*/
|
||||
|
||||
ExceptionTableEntry(short start, short stop,
|
||||
short handler, ClassConstant eType) {
|
||||
super();
|
||||
|
||||
startPC = start;
|
||||
stopPC = stop;
|
||||
handlerPC = handler;
|
||||
exceptionType = eType;
|
||||
}
|
||||
|
||||
/*
|
||||
* wrote the exception table entry to the stream
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeShort(startPC);
|
||||
dos.writeShort(stopPC);
|
||||
dos.writeShort(handlerPC);
|
||||
if (exceptionType != null)
|
||||
dos.writeShort(exceptionType.getConstantPoolIndex());
|
||||
else
|
||||
dos.writeShort(0);
|
||||
}
|
||||
}
|
133
src/FESI/ClassFile/ConstantPoolEntry.java
Normal file
133
src/FESI/ClassFile/ConstantPoolEntry.java
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
*
|
||||
* @(#) ConstantPoolEntry.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.ConstantPoolEntry
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The ConstantPoolEntry is an abstract base class representing common
|
||||
* behaviors of specific subtypes, as defined below and in the VM spec.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* In particular this class handles, equality, sharing, output and indexing
|
||||
* of all subtypes.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
abstract class ConstantPoolEntry {
|
||||
|
||||
/*
|
||||
* subtype tag values.
|
||||
*/
|
||||
|
||||
final static byte CONSTANT_UTF8 = 1;
|
||||
final static byte CONSTANT_UNICODE = 2;
|
||||
final static byte CONSTANT_INTEGER = 3;
|
||||
final static byte CONSTANT_FLOAT = 4;
|
||||
final static byte CONSTANT_LONG = 5;
|
||||
final static byte CONSTANT_DOUBLE = 6;
|
||||
final static byte CONSTANT_CLASS = 7;
|
||||
final static byte CONSTANT_STRING = 8;
|
||||
final static byte CONSTANT_FIELDREF = 9;
|
||||
final static byte CONSTANT_METHODREF = 10;
|
||||
final static byte CONSTANT_INTERFACEMETHODREF = 11;
|
||||
final static byte CONSTANT_NAMEANDTYPE = 12;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
private byte tag;
|
||||
|
||||
private ClassFile classFile;
|
||||
|
||||
private short index = -1;
|
||||
|
||||
/**
|
||||
* <p> construct the CPE, set the type tag and class file </p>
|
||||
*/
|
||||
|
||||
ConstantPoolEntry(byte t, ClassFile cf) {
|
||||
tag = t;
|
||||
classFile = cf;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
byte getTag() { return tag; }
|
||||
|
||||
/**
|
||||
* @return the CPE's constant pool index.
|
||||
*/
|
||||
|
||||
short getConstantPoolIndex() {
|
||||
if (index == -1) index = classFile.addConstantPoolEntry(this);
|
||||
|
||||
return (short)index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Class File this CPE is contained within.
|
||||
*/
|
||||
|
||||
ClassFile getClassFile() { return classFile; };
|
||||
|
||||
/**
|
||||
* <p> * write the CPE to the stream </p>
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
abstract void write(DataOutputStream dos) throws IOException;
|
||||
|
||||
/**
|
||||
* <p> test the CPE for equality </p>
|
||||
*
|
||||
* @return object's equality.
|
||||
*/
|
||||
|
||||
public abstract boolean equals(Object o);
|
||||
|
||||
/**
|
||||
* <p> add the CPE into the Class File's constant pool </p>
|
||||
*/
|
||||
|
||||
protected void addToConstantPool() {
|
||||
if (index == -1) index = classFile.addConstantPoolEntry(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return are we in debug mode?
|
||||
*/
|
||||
|
||||
protected static boolean debug() { return ClassFile.debug(); }
|
||||
}
|
157
src/FESI/ClassFile/ConstantValue.java
Normal file
157
src/FESI/ClassFile/ConstantValue.java
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
*
|
||||
* @(#) ConstantValue.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.ConstantValue
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.Attribute;
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
import FESI.ClassFile.IntegerConstant;
|
||||
import FESI.ClassFile.FloatConstant;
|
||||
import FESI.ClassFile.DoubleConstant;
|
||||
import FESI.ClassFile.LongConstant;
|
||||
import FESI.ClassFile.StringConstant;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This class provides Constant Pool support for all the simple constant
|
||||
* value data types supported in the class file format.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
class ConstantValue extends Attribute {
|
||||
|
||||
private ConstantPoolEntry constant;
|
||||
|
||||
/**
|
||||
* <p> construct an Attribute describing a Constant </p>
|
||||
*
|
||||
* @param cf the class file
|
||||
* @param cpe the cpe of the constant
|
||||
*/
|
||||
|
||||
private ConstantValue(ClassFile cf, ConstantPoolEntry cpe) {
|
||||
super(Attribute.CONSTANTVALUE, cf);
|
||||
constant = cpe;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Integer Constant </p>
|
||||
*
|
||||
* @param cf the class file
|
||||
* @param ic the Integer Constant
|
||||
*/
|
||||
|
||||
ConstantValue(ClassFile cf, IntegerConstant ic) {
|
||||
this(cf, (ConstantPoolEntry)ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Long Constant </p>
|
||||
*
|
||||
* @param cf the class file
|
||||
* @param lc the Long Constant
|
||||
*/
|
||||
|
||||
ConstantValue(ClassFile cf, LongConstant lc) {
|
||||
this(cf, (ConstantPoolEntry)lc);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Float Constant </p>
|
||||
*
|
||||
* @param cf the class file
|
||||
* @param fc the Float Constant
|
||||
*/
|
||||
|
||||
ConstantValue(ClassFile cf, FloatConstant fc) {
|
||||
this(cf, (ConstantPoolEntry)fc);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Double Constant </p>
|
||||
*
|
||||
* @param cf the class file
|
||||
* @param dc the Double Constant
|
||||
*/
|
||||
|
||||
ConstantValue(ClassFile cf, DoubleConstant dc) {
|
||||
this(cf, (ConstantPoolEntry)dc);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> String Constant </p>
|
||||
*
|
||||
* @param cf the class file
|
||||
* @param sc the String Constant
|
||||
*/
|
||||
|
||||
ConstantValue(ClassFile cf, StringConstant sc) {
|
||||
this(cf, (ConstantPoolEntry)sc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the length of this ConstantValue Attribute (minus header)
|
||||
*/
|
||||
|
||||
int getLength() { return 2; }
|
||||
|
||||
/**
|
||||
* @return the CPE of the constant represented
|
||||
*/
|
||||
|
||||
ConstantPoolEntry getConstant() { return constant; }
|
||||
|
||||
/**
|
||||
* @return the CPE type tag of the constant represented
|
||||
*/
|
||||
|
||||
byte getConstantTag() { return constant.getTag(); }
|
||||
|
||||
/**
|
||||
*<p> write the Attribute to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeShort(getNameConstantPoolIndex());
|
||||
dos.writeInt(getLength());
|
||||
dos.writeShort(constant.getConstantPoolIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the objects equality.
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return constant.equals(o);
|
||||
}
|
||||
}
|
91
src/FESI/ClassFile/DoubleConstant.java
Normal file
91
src/FESI/ClassFile/DoubleConstant.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
*
|
||||
* @(#) DoubleConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.DoubleConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
|
||||
/**
|
||||
* <p> implements a DOUBLE_CONSTANT CPE </p>
|
||||
*/
|
||||
|
||||
class DoubleConstant extends ConstantPoolEntry {
|
||||
|
||||
private double doubler;
|
||||
|
||||
/**
|
||||
* <p> construct a DOUBLE_CONSTANT CPE </p>
|
||||
*
|
||||
* @param d the double constant
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
DoubleConstant(double d, ClassFile cf) {
|
||||
super(CONSTANT_DOUBLE, cf);
|
||||
|
||||
doubler = d;
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the constant CPE to the stream </p>
|
||||
*
|
||||
* @param dos the stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeByte(getTag());
|
||||
dos.writeDouble(doubler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the double constant value.
|
||||
*/
|
||||
|
||||
double getValue() { return doubler; }
|
||||
|
||||
/**
|
||||
* @return the object's equality.
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Double) {
|
||||
return doubler == ((Double)o).doubleValue();
|
||||
} else if (o instanceof DoubleConstant) {
|
||||
DoubleConstant dc = (DoubleConstant)o;
|
||||
|
||||
return doubler == dc.getValue();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
809
src/FESI/ClassFile/EventAdaptorClassFile.java
Normal file
809
src/FESI/ClassFile/EventAdaptorClassFile.java
Normal file
|
@ -0,0 +1,809 @@
|
|||
/*
|
||||
*
|
||||
* @(#) EncapsulatedEventAdaptorClassFile.java 1.3@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.EncapsulatedEventAdaptorClassFile
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import FESI.Interpreter.EventAdaptor;
|
||||
import FESI.Interpreter.EventAdaptorGenerator;
|
||||
|
||||
import FESI.ClassFile.Attribute;
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ClassConstant;
|
||||
import FESI.ClassFile.Code;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
import FESI.ClassFile.Exceptions;
|
||||
import FESI.ClassFile.IntegerConstant;
|
||||
import FESI.ClassFile.FieldDesc;
|
||||
import FESI.ClassFile.FieldConstant;
|
||||
import FESI.ClassFile.MethodDesc;
|
||||
import FESI.ClassFile.MethodConstant;
|
||||
import FESI.ClassFile.StringConstant;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This class is used by the EventAdaptorGenerator to author the
|
||||
* implementation of the EventAdaptor classes that it is responsible
|
||||
* for generating and loading.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* This class wraps all the ClassFile generic support classes and provides
|
||||
* the adaptor specific implemenetation.
|
||||
* </p>
|
||||
*
|
||||
* @see FESI.Interpreter.EventAdaptorGenerator
|
||||
*/
|
||||
|
||||
public final class EventAdaptorClassFile {
|
||||
|
||||
private static String superClassName =
|
||||
"FESI.Interpreter.EventAdaptor";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
private String listenerName;
|
||||
private Class listenerClass;
|
||||
|
||||
private String adaptorName;
|
||||
private ClassFile classFile;
|
||||
|
||||
private Method[] listenerMethods;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
private StringConstant listenerNameConst;
|
||||
|
||||
private FieldConstant methodsField;
|
||||
private FieldConstant clazzField;
|
||||
|
||||
private MethodConstant fireMethod;
|
||||
private MethodConstant crackedFireMethod;
|
||||
|
||||
private MethodConstant forNameMethod;
|
||||
|
||||
private MethodConstant getMethodsMethod;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This statis function creates the class file implementation and writes
|
||||
* it to the stream for loading ...
|
||||
* </p>
|
||||
*
|
||||
* @param className the name of the adaptor class to synthesize.
|
||||
* @param os the stream to write the class file into
|
||||
* @exception IOException If any IO error occured during class loading
|
||||
* @exception ClassNotFoundException If the class could not be loaded
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
|
||||
public EventAdaptorClassFile(String className, OutputStream os)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
adaptorName = className;
|
||||
listenerName = EventAdaptorGenerator.getBaseNameFromAdaptorName(className);
|
||||
|
||||
listenerClass = Class.forName(listenerName);
|
||||
|
||||
listenerMethods = listenerClass.getMethods();
|
||||
|
||||
classFile = new ClassFile(className, superClassName);
|
||||
|
||||
// generate the misc class descriptions ...
|
||||
|
||||
generateClassSundries();
|
||||
|
||||
// generate the class initializer
|
||||
|
||||
generateInitializer();
|
||||
|
||||
// now the constructor ...
|
||||
|
||||
generateConstructor();
|
||||
|
||||
// now the methods ...
|
||||
|
||||
generateListenerMethods();
|
||||
|
||||
// write the resulting adaptor class to the stream provided.
|
||||
|
||||
write(os);
|
||||
}
|
||||
|
||||
/**
|
||||
* Are we running debug for this Adaptor generation?
|
||||
*/
|
||||
|
||||
private boolean debug() { return false; }
|
||||
|
||||
/**
|
||||
* Generate misc constant pool entries etc etc ...
|
||||
*/
|
||||
|
||||
private void generateClassSundries() {
|
||||
|
||||
// the adaptor implements the Listener interface.
|
||||
|
||||
classFile.addInterface(ClassFile.fullyQualifiedForm(listenerName));
|
||||
|
||||
listenerNameConst = classFile.addStringConstant(listenerName);
|
||||
|
||||
/*
|
||||
* private static java.lang.reflect.Method[] methods;
|
||||
*/
|
||||
|
||||
classFile.addFieldDesc(
|
||||
new FieldDesc(
|
||||
"methods",
|
||||
"[Ljava/lang/reflect/Method;",
|
||||
(short)(FieldDesc.ACC_STATIC | FieldDesc.ACC_PRIVATE),
|
||||
classFile,
|
||||
(Attribute[])null
|
||||
)
|
||||
);
|
||||
|
||||
methodsField = classFile.addFieldConstant(adaptorName,
|
||||
"methods",
|
||||
"[Ljava/lang/reflect/Method;"
|
||||
);
|
||||
|
||||
/*
|
||||
* java.lang.reflect.Method[] java.lang.reflect.Method.getMethods();
|
||||
*/
|
||||
|
||||
getMethodsMethod = classFile.addMethodConstant(
|
||||
"java/lang/Class",
|
||||
"getMethods",
|
||||
"()[Ljava/lang/reflect/Method;"
|
||||
);
|
||||
|
||||
/*
|
||||
* java.lang.Class java.lang.Class.forName();
|
||||
*/
|
||||
|
||||
forNameMethod = classFile.addMethodConstant(
|
||||
"java/lang/Class",
|
||||
"forName",
|
||||
"(Ljava/lang/String;)Ljava/lang/Class;"
|
||||
);
|
||||
/*
|
||||
* private static java.lang.Class clazz;
|
||||
*/
|
||||
|
||||
classFile.addFieldDesc(
|
||||
new FieldDesc(
|
||||
"clazz",
|
||||
"Ljava/lang/Class;",
|
||||
(short)(FieldDesc.ACC_STATIC | FieldDesc.ACC_PRIVATE),
|
||||
classFile,
|
||||
(Attribute[])null
|
||||
)
|
||||
);
|
||||
|
||||
clazzField = classFile.addFieldConstant(adaptorName,
|
||||
"clazz",
|
||||
"Ljava/lang/Class;"
|
||||
);
|
||||
|
||||
/*
|
||||
* these are superclass methods called from listener stubs ...
|
||||
*/
|
||||
|
||||
fireMethod = classFile.addMethodConstant(
|
||||
adaptorName,
|
||||
"fire",
|
||||
"(Ljava/util/EventObject;Ljava/lang/reflect/Method;)V"
|
||||
);
|
||||
|
||||
crackedFireMethod = classFile.addMethodConstant(
|
||||
adaptorName,
|
||||
"fire",
|
||||
"([Ljava/lang/Object;Ljava/lang/reflect/Method;)V"
|
||||
);
|
||||
|
||||
/*
|
||||
* stub out base class abstract method:
|
||||
*
|
||||
* public static Class getListenerClass() { return clazz; }
|
||||
*
|
||||
*/
|
||||
|
||||
Code c = new Code(classFile, (short)1, (short)2);
|
||||
|
||||
c.addOpShort(Code.OP_GETSTATIC, clazzField.getConstantPoolIndex());
|
||||
c.addOp (Code.OP_ARETURN);
|
||||
|
||||
Code[] ary = { c };
|
||||
|
||||
classFile.addMethodDesc(
|
||||
new MethodDesc(
|
||||
"getListenerClass",
|
||||
"()Ljava/lang/Class;",
|
||||
(short)MethodDesc.ACC_PUBLIC,
|
||||
classFile,
|
||||
ary
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Generate class Initializer method </p>
|
||||
*/
|
||||
|
||||
private void generateInitializer() {
|
||||
Code c = new Code(classFile, (short)0, (short)3);
|
||||
Code[] ary = { c };
|
||||
short i = listenerNameConst.getConstantPoolIndex();
|
||||
|
||||
|
||||
// clazz = Class.forName( <The_Listener_Interface> );
|
||||
|
||||
if (i <= 255)
|
||||
c.addOp1(Code.OP_LDC, (byte)i);
|
||||
else
|
||||
c.addOpShort(Code.OP_LDC_WIDE, i);
|
||||
|
||||
c.addOpShort(Code.OP_INVOKE_STATIC,
|
||||
forNameMethod.getConstantPoolIndex()
|
||||
);
|
||||
|
||||
c.addOp(Code.OP_DUP);
|
||||
|
||||
c.addOpShort(Code.OP_PUTSTATIC,
|
||||
clazzField.getConstantPoolIndex()
|
||||
);
|
||||
|
||||
|
||||
// methods = clazz.getMethods();
|
||||
|
||||
c.addOpShort(Code.OP_INVOKE_VIRTUAL,
|
||||
getMethodsMethod.getConstantPoolIndex()
|
||||
);
|
||||
|
||||
c.addOpShort(Code.OP_PUTSTATIC,
|
||||
methodsField.getConstantPoolIndex()
|
||||
);
|
||||
|
||||
c.addOp (Code.OP_RETURN);
|
||||
|
||||
classFile.addMethodDesc(
|
||||
new MethodDesc(
|
||||
"<clinit>",
|
||||
"()V",
|
||||
(short)(MethodDesc.ACC_PRIVATE | MethodDesc.ACC_STATIC),
|
||||
classFile,
|
||||
ary
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Author the no-args public constructor for this Adaptor
|
||||
*
|
||||
* public void <init>() { super(); }
|
||||
*/
|
||||
|
||||
private void generateConstructor() {
|
||||
Code c = new Code(classFile, (short)1, (short)2);
|
||||
Code[] ary = { c };
|
||||
MethodConstant mc;
|
||||
|
||||
// get a MethodConstant for the superclass constructor
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
ClassFile.fullyQualifiedForm(superClassName),
|
||||
"<init>",
|
||||
"()V"
|
||||
);
|
||||
|
||||
// push this onto the stack
|
||||
|
||||
c.addOp (Code.OP_ALOAD_0);
|
||||
|
||||
// call the superclass constructor
|
||||
|
||||
c.addOpShort(Code.OP_INVOKE_SPECIAL, mc.getConstantPoolIndex());
|
||||
|
||||
c.addOp (Code.OP_RETURN);
|
||||
|
||||
|
||||
// now add a method to the class file describing the constructor ...
|
||||
|
||||
classFile.addMethodDesc(
|
||||
new MethodDesc(
|
||||
"<init>",
|
||||
"()V",
|
||||
(short)MethodDesc.ACC_PUBLIC,
|
||||
classFile,
|
||||
ary
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Author the Listener Method Stubs for the EventListener interface
|
||||
* this class is adapting to the EventListener interface.
|
||||
*/
|
||||
|
||||
private void generateListenerMethods() {
|
||||
for (int i = 0; i < listenerMethods.length; i++) {
|
||||
|
||||
/* we can only generate code for EventListener methods of
|
||||
* the form:
|
||||
*
|
||||
* void <method_name> ( <EventObject Subtype> )
|
||||
* or:
|
||||
* void <method_name> ( {<arbitrary arg list>} )
|
||||
*
|
||||
* if we dont match these patterns we drop the method on the
|
||||
* floor.
|
||||
*/
|
||||
|
||||
if (!Void.TYPE.equals(listenerMethods[i].getReturnType())) {
|
||||
System.err.println(
|
||||
"Detected unexpected method signature: " +
|
||||
listenerMethods[i] +
|
||||
" in interface: " +
|
||||
listenerName
|
||||
);
|
||||
} else {
|
||||
Class[] lmParams = listenerMethods[i].getParameterTypes();
|
||||
Class[] lmExceptions = listenerMethods[i].getExceptionTypes();
|
||||
|
||||
|
||||
if (lmParams != null &&
|
||||
lmParams.length == 1 &&
|
||||
java.util.EventObject.class.isAssignableFrom(lmParams[0])) {
|
||||
generateSimpleListenerMethodStub(listenerMethods[i],
|
||||
lmParams[0],
|
||||
lmExceptions,
|
||||
i
|
||||
);
|
||||
} else {
|
||||
generateCrackedListenerMethodStub(listenerMethods[i],
|
||||
lmParams,
|
||||
lmExceptions,
|
||||
i
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a simple EventListener interface method stub
|
||||
*/
|
||||
|
||||
private void generateSimpleListenerMethodStub(Method listenerMethod, Class listenerParam, Class[] listenerExceptions, int listenerMethodTableIndex) {
|
||||
Code c = new Code(classFile, (short)2, (short)4);
|
||||
Attribute[] ary;
|
||||
|
||||
/*
|
||||
* public void <EventListenerMethod>(<EventObject> e)
|
||||
* {
|
||||
* EncapsulatedEvent t = new EncapsulatedEvent(e);
|
||||
* Method m = findListenerMethod();
|
||||
*
|
||||
* fire(t, m);
|
||||
* }
|
||||
*/
|
||||
|
||||
c.addOp (Code.OP_ALOAD_0); // this
|
||||
c.addOp (Code.OP_ALOAD_1); // event object
|
||||
|
||||
c.addOpShort(Code.OP_GETSTATIC,
|
||||
methodsField.getConstantPoolIndex()
|
||||
);
|
||||
|
||||
if (listenerMethodTableIndex <= 255) {
|
||||
c.addOp1(Code.OP_BIPUSH, (byte)listenerMethodTableIndex);
|
||||
} else {
|
||||
short i = classFile.addIntegerConstant(listenerMethodTableIndex).getConstantPoolIndex();
|
||||
|
||||
if (i <= 255)
|
||||
c.addOp1(Code.OP_LDC, (byte)i);
|
||||
else
|
||||
c.addOpShort(Code.OP_LDC_WIDE, i);
|
||||
}
|
||||
|
||||
c.addOp (Code.OP_AALOAD);
|
||||
|
||||
c.addOpShort(Code.OP_INVOKE_VIRTUAL,
|
||||
fireMethod.getConstantPoolIndex()
|
||||
); // call fire();
|
||||
|
||||
c.addOp (Code.OP_RETURN); // get out of here
|
||||
|
||||
if (listenerExceptions != null && listenerExceptions.length > 0) {
|
||||
ary = new Attribute[2];
|
||||
|
||||
ary[1] = new Exceptions(listenerExceptions, classFile);
|
||||
} else {
|
||||
ary = new Attribute[1];
|
||||
}
|
||||
|
||||
ary[0] = c;
|
||||
|
||||
// define the listener method
|
||||
|
||||
classFile.addMethodDesc(
|
||||
new MethodDesc(
|
||||
listenerMethod.getName(),
|
||||
"(" + ClassFile.fieldType(listenerParam.getName()) + ")V",
|
||||
(short)(listenerMethod.getModifiers() & ~MethodDesc.ACC_ABSTRACT),
|
||||
classFile,
|
||||
ary
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a cracked EventListener interface method stub
|
||||
*/
|
||||
|
||||
private void generateCrackedListenerMethodStub(Method listenerMethod, Class[] listenerParams, Class[] listenerExceptions, int listenerMethodTableIndex) {
|
||||
Code c = new Code(classFile,
|
||||
(short)(listenerParams.length * 2 + 1),
|
||||
(short)9
|
||||
);
|
||||
Attribute[] ary;
|
||||
String methodPDesc = "";
|
||||
boolean wasDoubleWord; // was the last param processed double?
|
||||
|
||||
c.addOp (Code.OP_ALOAD_0); // this
|
||||
|
||||
/*
|
||||
* For cracked Event listener methods we construct an array of Objects
|
||||
* to contain the cracked actual parameters ... primitive types are
|
||||
* wrapped in a container object suitable for their type.
|
||||
*/
|
||||
|
||||
if (listenerParams.length <= 255) {
|
||||
c.addOp1(Code.OP_BIPUSH, (byte)listenerParams.length);
|
||||
} else {
|
||||
short i = classFile.addIntegerConstant(listenerParams.length).getConstantPoolIndex();
|
||||
|
||||
if (i <= 255)
|
||||
c.addOp1(Code.OP_LDC, (byte)i);
|
||||
else
|
||||
c.addOpShort(Code.OP_LDC_WIDE, (short)i);
|
||||
}
|
||||
|
||||
c.addOpShort(Code.OP_ANEWARRAY,
|
||||
classFile.addClassConstant("java.lang.Object").getConstantPoolIndex()
|
||||
);
|
||||
|
||||
/*
|
||||
* we've now constructed and array of java/lang/Object ... now populate
|
||||
* it with the actual params.
|
||||
*/
|
||||
|
||||
int lvarIdx = 1; // because locals[0] == this
|
||||
|
||||
/*
|
||||
* for each formal parameter, generate code to load the actual
|
||||
* param from this methods local vars, then if it is a primitive
|
||||
* type, then construct a container object and initialize it
|
||||
* to the primitives value.
|
||||
*
|
||||
* as a side effect of this loop we also construct the methods
|
||||
* descriptor to optimise processing of the type info
|
||||
*/
|
||||
|
||||
for (int i = 0; i < listenerParams.length; i++, lvarIdx += (wasDoubleWord ? 2 : 1)) {
|
||||
|
||||
c.addOp(Code.OP_DUP); // the array reference
|
||||
|
||||
if (lvarIdx <= 255) { // the array index
|
||||
c.addOp1(Code.OP_BIPUSH, (byte)i);
|
||||
} else {
|
||||
short ic = classFile.addIntegerConstant(i).getConstantPoolIndex();
|
||||
if (ic < 255)
|
||||
c.addOp1(Code.OP_LDC, (byte)ic);
|
||||
else
|
||||
c.addOpShort(Code.OP_LDC_WIDE, (short)ic);
|
||||
}
|
||||
|
||||
/*
|
||||
* get the param value onto TOS
|
||||
* as a side effect gather method descriptor string.
|
||||
*/
|
||||
|
||||
String s = processParam(c, listenerParams[i], lvarIdx);
|
||||
|
||||
c.addOp(Code.OP_AASTORE); // arrayref, index, value
|
||||
|
||||
wasDoubleWord = s.equals("J") || s.equals("D");
|
||||
|
||||
methodPDesc += s;
|
||||
}
|
||||
|
||||
// that's the array constructed ... now lets call my superclass fire
|
||||
|
||||
// but first we need to tell that method which listener is firing ...
|
||||
|
||||
c.addOpShort(Code.OP_GETSTATIC,
|
||||
methodsField.getConstantPoolIndex()
|
||||
);
|
||||
|
||||
if (listenerMethodTableIndex <= 255) {
|
||||
c.addOp1(Code.OP_BIPUSH, (byte)listenerMethodTableIndex);
|
||||
} else {
|
||||
short i = classFile.addIntegerConstant(listenerMethodTableIndex).getConstantPoolIndex();
|
||||
|
||||
if (i <= 255)
|
||||
c.addOp1(Code.OP_LDC, (byte)i);
|
||||
else
|
||||
c.addOpShort(Code.OP_LDC_WIDE, i);
|
||||
}
|
||||
|
||||
c.addOp (Code.OP_AALOAD); // this, array, method
|
||||
|
||||
// now we can call the fire method
|
||||
|
||||
c.addOpShort(Code.OP_INVOKE_VIRTUAL,
|
||||
crackedFireMethod.getConstantPoolIndex()
|
||||
); // call fire();
|
||||
|
||||
c.addOp (Code.OP_RETURN); // get out of here
|
||||
|
||||
if (listenerExceptions != null && listenerExceptions.length > 0) {
|
||||
ary = new Attribute[2];
|
||||
|
||||
ary[1] = new Exceptions(listenerExceptions, classFile);
|
||||
} else {
|
||||
ary = new Attribute[1];
|
||||
}
|
||||
|
||||
ary[0] = c;
|
||||
|
||||
// define the listener method
|
||||
|
||||
classFile.addMethodDesc(
|
||||
new MethodDesc(
|
||||
listenerMethod.getName(),
|
||||
"(" + methodPDesc + ")V",
|
||||
(short)(listenerMethod.getModifiers() & ~MethodDesc.ACC_ABSTRACT),
|
||||
classFile,
|
||||
ary
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* This method is used to generate code for cracked event listener
|
||||
* stubs. Its job is to generate code to load the appropriate parameter
|
||||
* data type onto the stack, create a wrapper object if needed and leave
|
||||
* the appropriate value on TOS for storing into the objects array.
|
||||
*/
|
||||
|
||||
private String processParam(Code c, Class pClass, int pIdx) {
|
||||
ClassConstant cc = null;
|
||||
MethodConstant mc = null;
|
||||
byte ldOpCode = Code.OP_ALOAD; // load ref by default
|
||||
byte convOpCode = 0;
|
||||
boolean singleWordParam = true;
|
||||
Class pType = pClass;
|
||||
boolean isPrimitive;
|
||||
boolean isArrayRef;
|
||||
|
||||
String pDesc = "";
|
||||
|
||||
// is this an array reference?
|
||||
|
||||
while (pType.isArray()) { // side - effect: construct array param desc
|
||||
pType = pType.getComponentType();
|
||||
pDesc += "[";
|
||||
}
|
||||
|
||||
isPrimitive = pType.isPrimitive();
|
||||
isArrayRef = pClass.isArray();
|
||||
|
||||
if (isPrimitive) { // builtin datatype
|
||||
if (pType.equals(java.lang.Long.TYPE)) {
|
||||
pDesc += "J";
|
||||
|
||||
if (!isArrayRef) {
|
||||
cc = classFile.addClassConstant("java/lang/Long");
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
"java/lang/Long",
|
||||
"<init>",
|
||||
"(J)V"
|
||||
);
|
||||
|
||||
ldOpCode = Code.OP_LLOAD;
|
||||
singleWordParam = false;
|
||||
}
|
||||
} else if (pType.equals(java.lang.Float.TYPE)) {
|
||||
pDesc += "F";
|
||||
|
||||
if (!isArrayRef) {
|
||||
cc = classFile.addClassConstant("java/lang/Float");
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
"java/lang/Float",
|
||||
"<init>",
|
||||
"(F)V"
|
||||
);
|
||||
|
||||
ldOpCode = Code.OP_FLOAD;
|
||||
}
|
||||
} else if (pType.equals(java.lang.Double.TYPE)) {
|
||||
pDesc += "D";
|
||||
|
||||
if (!isArrayRef) {
|
||||
cc = classFile.addClassConstant("java/lang/Double");
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
"java/lang/Double",
|
||||
"<init>",
|
||||
"(D)V"
|
||||
);
|
||||
|
||||
ldOpCode = Code.OP_DLOAD;
|
||||
singleWordParam = false;
|
||||
}
|
||||
} else { // integer, array or objref computational types ...
|
||||
|
||||
ldOpCode = Code.OP_ILOAD;
|
||||
|
||||
if (pType.equals(java.lang.Boolean.TYPE)) {
|
||||
pDesc += "Z";
|
||||
|
||||
if (!isArrayRef) {
|
||||
cc = classFile.addClassConstant("java/lang/Boolean");
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
"java/lang/Boolean",
|
||||
"<init>",
|
||||
"(Z)V"
|
||||
);
|
||||
|
||||
convOpCode = Code.OP_I2B;
|
||||
}
|
||||
} else if (pType.equals(java.lang.Character.TYPE)) {
|
||||
pDesc += "C";
|
||||
|
||||
if (!isArrayRef) {
|
||||
cc = classFile.addClassConstant("java/lang/Character");
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
"java/lang/Character",
|
||||
"<init>",
|
||||
"(C)V"
|
||||
);
|
||||
|
||||
convOpCode = Code.OP_I2C;
|
||||
}
|
||||
} else if (pType.equals(java.lang.Byte.TYPE)) {
|
||||
pDesc += "B";
|
||||
|
||||
if (!isArrayRef) {
|
||||
cc = classFile.addClassConstant("java/lang/Byte");
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
"java/lang/Character",
|
||||
"<init>",
|
||||
"(C)V"
|
||||
);
|
||||
|
||||
convOpCode = Code.OP_I2B;
|
||||
}
|
||||
} else if (pType.equals(java.lang.Short.TYPE)) {
|
||||
pDesc += "S";
|
||||
|
||||
if (!isArrayRef) {
|
||||
cc = classFile.addClassConstant("java/lang/Short");
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
"java/lang/Short",
|
||||
"<init>",
|
||||
"(S)V"
|
||||
);
|
||||
|
||||
convOpCode = Code.OP_I2S;
|
||||
}
|
||||
} else if (pType.equals(java.lang.Integer.TYPE)) {
|
||||
pDesc += "I";
|
||||
|
||||
if (!isArrayRef) {
|
||||
cc = classFile.addClassConstant("java/lang/Integer");
|
||||
|
||||
mc = classFile.addMethodConstant(
|
||||
"java/lang/Integer",
|
||||
"<init>",
|
||||
"(I)V"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // handle descriptors for non-primitives ...
|
||||
pDesc += ClassFile.fieldType(pType.getName());
|
||||
}
|
||||
|
||||
// now load the param value onto TOS ...
|
||||
|
||||
if (pIdx < 255)
|
||||
c.addOp1(ldOpCode, (byte)pIdx);
|
||||
else {
|
||||
c.addOp(Code.OP_WIDE);
|
||||
c.addOpShort(ldOpCode, (short)pIdx);
|
||||
}
|
||||
|
||||
if (isPrimitive && !isArrayRef) { // additional processing for primitives
|
||||
if (convOpCode != 0) { // narrow Int?
|
||||
c.addOp(convOpCode); // then widen the reference
|
||||
}
|
||||
|
||||
// we now have the param's value of TOS,
|
||||
// construct a container object for it
|
||||
|
||||
c.addOpShort(Code.OP_NEW, (short)cc.getConstantPoolIndex());
|
||||
|
||||
if (singleWordParam) {
|
||||
c.addOp(Code.OP_DUP_X1); // this, <param_word>, this
|
||||
c.addOp(Code.OP_SWAP); // this, <param_word>
|
||||
} else {
|
||||
c.addOp(Code.OP_DUP_X2); // this, <param_2word>, this
|
||||
c.addOp(Code.OP_DUP_X2); // this, this, <param_2word>, this
|
||||
c.addOp(Code.OP_POP); // this, this, <param_2word>
|
||||
}
|
||||
|
||||
c.addOpShort(Code.OP_INVOKE_SPECIAL, mc.getConstantPoolIndex());
|
||||
}
|
||||
|
||||
// param value on TOS
|
||||
|
||||
return pDesc; // type descriptor - side effect
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the class file to the stream </p>
|
||||
*
|
||||
* @param os the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
private void write(OutputStream os) throws IOException {
|
||||
classFile.write(os);
|
||||
}
|
||||
}
|
160
src/FESI/ClassFile/Exceptions.java
Normal file
160
src/FESI/ClassFile/Exceptions.java
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
*
|
||||
* @(#) Exceptions.java 1.3@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.Exceptions
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.Attribute;
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ClassConstant;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The Exceptions class extends the Attribute class to enumerate the
|
||||
* exception types generated by method implementations in a class file
|
||||
* </p>
|
||||
*/
|
||||
|
||||
class Exceptions extends Attribute {
|
||||
|
||||
private ClassConstant[] exceptions;
|
||||
|
||||
/**
|
||||
* <p> construct an Exceptions attribute that enumerates the exceptions </p>
|
||||
*
|
||||
* @param exs[] an array of exception class constants
|
||||
* @param cf the containing class file
|
||||
*/
|
||||
|
||||
Exceptions(ClassConstant[] exs, ClassFile cf) {
|
||||
super(Attribute.EXCEPTIONS, cf);
|
||||
|
||||
// we should validate that the ClassConstants are all
|
||||
// subclasses of Exception here ...
|
||||
|
||||
exceptions = exs;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> construct an Exceptions attribute that enumerates the exceptions </p>
|
||||
*
|
||||
* @param exs[] an array of exception class types
|
||||
* @param cf the containing class file
|
||||
*
|
||||
*/
|
||||
Exceptions(Class[] exs, ClassFile cf) {
|
||||
super(Attribute.EXCEPTIONS, cf);
|
||||
|
||||
// we should validate that the ClassConstants are all
|
||||
// subclasses of Exception here ...
|
||||
|
||||
ClassConstant[] cc = new ClassConstant[exs.length];
|
||||
|
||||
for (int i = 0; i < exs.length; i++)
|
||||
cc[i] = cf.addClassConstant(exs[i].getName());
|
||||
|
||||
exceptions = cc;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the Exceptions attribute to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeShort(getNameConstantPoolIndex());
|
||||
dos.writeInt(getLength());
|
||||
|
||||
if (exceptions != null && exceptions.length > 0) {
|
||||
dos.writeShort(exceptions.length);
|
||||
|
||||
for (int i = 0; i < exceptions.length; i++) {
|
||||
dos.writeShort(exceptions[i].getConstantPoolIndex());
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Object's equality
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Exceptions) {
|
||||
Exceptions other = (Exceptions)o;
|
||||
|
||||
if (exceptions.length == other.exceptions.length) {
|
||||
for (int i = 0; i < exceptions.length; i++) {
|
||||
if (!exceptions[i].equals(other.exceptions[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the length of the Attribute in bytes
|
||||
*/
|
||||
|
||||
int getLength() { return exceptions.length * 2 + 2; }
|
||||
|
||||
/**
|
||||
* <p> adds exception class to the attribute. </p>
|
||||
*
|
||||
* @param a class constant to add to the attribute
|
||||
*
|
||||
*/
|
||||
|
||||
void addException(ClassConstant ex) {
|
||||
|
||||
// should verify that ClassConstant is exception subclass and not
|
||||
// already in the attribute
|
||||
|
||||
if (exceptions == null) {
|
||||
exceptions = new ClassConstant[1];
|
||||
|
||||
exceptions[0] = ex;
|
||||
} else {
|
||||
ClassConstant[] temp = new ClassConstant[exceptions.length + 1];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < exceptions.length; i++) {
|
||||
temp[i] = exceptions[i];
|
||||
}
|
||||
|
||||
temp[i] = ex;
|
||||
|
||||
exceptions = temp;
|
||||
}
|
||||
}
|
||||
}
|
49
src/FESI/ClassFile/FieldConstant.java
Normal file
49
src/FESI/ClassFile/FieldConstant.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
*
|
||||
* @(#) FieldConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.FieldConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.RefConstant;
|
||||
|
||||
/**
|
||||
* <p> implements a CONSTANT_FIELDREF CPE </p>
|
||||
*/
|
||||
|
||||
final class FieldConstant extends RefConstant {
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_FIELDREF CPE </p>
|
||||
*
|
||||
* @param cName the class name
|
||||
* @param nName the name of the field
|
||||
* @param tName the type descriptor for the field
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
FieldConstant(String cName, String nName, String tName, ClassFile cf) {
|
||||
super(CONSTANT_FIELDREF, cName, nName, tName, cf);
|
||||
}
|
||||
}
|
107
src/FESI/ClassFile/FieldDesc.java
Normal file
107
src/FESI/ClassFile/FieldDesc.java
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
*
|
||||
* @(#) FieldDesc.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.FieldDesc
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.UTF8Constant;
|
||||
import FESI.ClassFile.Attribute;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Implements the field_info structure of a class file, used to describe
|
||||
* the attributes of all fields implemented by this class. The class provides
|
||||
* minimal support to write the formatted structure to the stream.
|
||||
* </p>
|
||||
*/
|
||||
|
||||
final class FieldDesc {
|
||||
|
||||
final static short ACC_PUBLIC = 0x0001;
|
||||
final static short ACC_PRIVATE = 0x0002;
|
||||
final static short ACC_PROTECTED = 0x0004;
|
||||
final static short ACC_STATIC = 0x0008;
|
||||
final static short ACC_FINAL = 0x0010;
|
||||
final static short ACC_VOLATILE = 0x0040;
|
||||
final static short ACC_TRANSIENT = 0x0080;
|
||||
|
||||
private UTF8Constant name;
|
||||
private UTF8Constant descriptor;
|
||||
|
||||
private short accessFlags;
|
||||
|
||||
private ClassFile classFile;
|
||||
|
||||
private Attribute[] attributes;
|
||||
|
||||
/**
|
||||
* <p> construct a descriptor for a field. </p>
|
||||
*
|
||||
* @param field name
|
||||
* @param desc its type descriptor
|
||||
* @param flags access flags
|
||||
* @param cf the class file
|
||||
* @param attrs any associated attributes
|
||||
*
|
||||
*/
|
||||
|
||||
FieldDesc(String field, String desc, short flags, ClassFile cf, Attribute[] attrs) {
|
||||
super();
|
||||
|
||||
// we would validate here ...
|
||||
|
||||
name = new UTF8Constant(field, cf);
|
||||
descriptor = new UTF8Constant(desc, cf);
|
||||
accessFlags = flags;
|
||||
classFile = cf;
|
||||
attributes = attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the field to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeShort(accessFlags);
|
||||
dos.writeShort(name.getConstantPoolIndex());
|
||||
dos.writeShort(descriptor.getConstantPoolIndex());
|
||||
|
||||
if (attributes != null && attributes.length == 0) {
|
||||
dos.writeShort(attributes.length);
|
||||
|
||||
for (int i = 0; i < attributes.length; i++) {
|
||||
attributes[i].write(dos);
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
}
|
||||
}
|
93
src/FESI/ClassFile/FloatConstant.java
Normal file
93
src/FESI/ClassFile/FloatConstant.java
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
*
|
||||
* @(#) FloatConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.FloatConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
|
||||
/**
|
||||
* <p> provides minimal support for FLOAT_CONSTANT CPE </p>
|
||||
*/
|
||||
|
||||
class FloatConstant extends ConstantPoolEntry {
|
||||
|
||||
private float floating;
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_FLOAT </p>
|
||||
*
|
||||
* @param f the float value
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
FloatConstant(float f, ClassFile cf) {
|
||||
super(CONSTANT_FLOAT, cf);
|
||||
|
||||
floating = f;
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the CONSTANT_FLOAT to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeByte(getTag());
|
||||
dos.writeFloat(floating);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> return the value of the constant </p>
|
||||
*
|
||||
* @return the value of the CONSTANT_FLOAT
|
||||
*/
|
||||
|
||||
float getValue() { return floating; }
|
||||
|
||||
/**
|
||||
* @return object equality
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Float) {
|
||||
return floating == ((Float)o).floatValue();
|
||||
} else if (o instanceof FloatConstant) {
|
||||
FloatConstant fc = (FloatConstant)o;
|
||||
|
||||
return floating == fc.getValue();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
91
src/FESI/ClassFile/IntegerConstant.java
Normal file
91
src/FESI/ClassFile/IntegerConstant.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
*
|
||||
* @(#) IntegerConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.IntegerConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
|
||||
/**
|
||||
* <p> this class provides minimal support for the CONSTANT_INTEGER CPE </p>
|
||||
*/
|
||||
|
||||
class IntegerConstant extends ConstantPoolEntry {
|
||||
|
||||
private int integer;
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_INTEGER CPE </p>
|
||||
*
|
||||
* @param i the integer constant
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
IntegerConstant(int i, ClassFile cf) {
|
||||
super(CONSTANT_INTEGER, cf);
|
||||
|
||||
integer = i;
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the CONSTANT_INTEGER to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeByte(getTag());
|
||||
dos.writeInt(integer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the CONSTANT_INTEGER
|
||||
*/
|
||||
|
||||
int getValue() { return integer; }
|
||||
|
||||
/**
|
||||
* @return object equality
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Integer) {
|
||||
return integer == ((Integer)o).intValue();
|
||||
} else if (o instanceof IntegerConstant) {
|
||||
IntegerConstant ic = (IntegerConstant)o;
|
||||
|
||||
return integer == ic.getValue();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
50
src/FESI/ClassFile/InterfaceMethodConstant.java
Normal file
50
src/FESI/ClassFile/InterfaceMethodConstant.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
*
|
||||
* @(#) InterfaceMethodConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.InterfaceMethodConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.RefConstant;
|
||||
|
||||
/**
|
||||
* <p> this class provides minimal support for CONSTANT_INTERFACEMETHODREF CPE's </p>
|
||||
*/
|
||||
|
||||
class InterfaceMethodConstant extends RefConstant {
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_INTERFACEMETHODREF </p>
|
||||
*
|
||||
* @param cName name of interface
|
||||
* @param nName name of method
|
||||
* @param tName method type descriptor
|
||||
* @param cf class file
|
||||
*
|
||||
*/
|
||||
|
||||
InterfaceMethodConstant(String cName, String nName, String tName, ClassFile cf) {
|
||||
super(CONSTANT_INTERFACEMETHODREF, cName, nName, tName, cf);
|
||||
}
|
||||
}
|
91
src/FESI/ClassFile/LongConstant.java
Normal file
91
src/FESI/ClassFile/LongConstant.java
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
*
|
||||
* @(#) LongConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.LongConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
|
||||
/**
|
||||
* <p> this class provides minimal support for CONSTANT_LONG CPE's </p>
|
||||
*/
|
||||
|
||||
class LongConstant extends ConstantPoolEntry {
|
||||
|
||||
private long longish;
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_LONG </p>
|
||||
*
|
||||
* @param l the long constant
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
LongConstant(long l, ClassFile cf) {
|
||||
super(CONSTANT_LONG, cf);
|
||||
|
||||
longish = l;
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the CONSTANT_LONG to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeByte(getTag());
|
||||
dos.writeLong(longish);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the long constant value
|
||||
*/
|
||||
|
||||
long getValue() { return longish; }
|
||||
|
||||
/**
|
||||
* @return object equality
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Long) {
|
||||
return longish == ((Long)o).longValue();
|
||||
} else if (o instanceof LongConstant) {
|
||||
LongConstant lc = (LongConstant)o;
|
||||
|
||||
return longish == lc.getValue();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
49
src/FESI/ClassFile/MethodConstant.java
Normal file
49
src/FESI/ClassFile/MethodConstant.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
*
|
||||
* @(#) MethodConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.MethodConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.RefConstant;
|
||||
|
||||
/**
|
||||
* <p> this class provides minimal support for the CONSTANT_METHODREF CPE </p>
|
||||
*/
|
||||
|
||||
class MethodConstant extends RefConstant {
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_METHODREF </p>
|
||||
*
|
||||
* @param cName the name of the implementing class
|
||||
* @param nName the name of the method
|
||||
* @param tName the type descriptor of the method
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
MethodConstant(String cName, String nName, String tName, ClassFile cf) {
|
||||
super(CONSTANT_METHODREF, cName, nName, tName, cf);
|
||||
}
|
||||
}
|
104
src/FESI/ClassFile/MethodDesc.java
Normal file
104
src/FESI/ClassFile/MethodDesc.java
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
*
|
||||
* @(#) MethodDesc.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.MethodDesc
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.UTF8Constant;
|
||||
import FESI.ClassFile.Attribute;
|
||||
|
||||
/**
|
||||
* <p> this class provides minimal support for method_info structures </p>
|
||||
*/
|
||||
|
||||
final class MethodDesc {
|
||||
|
||||
final static short ACC_PUBLIC = 0x0001;
|
||||
final static short ACC_PRIVATE = 0x0002;
|
||||
final static short ACC_PROTECTED = 0x0004;
|
||||
final static short ACC_STATIC = 0x0008;
|
||||
final static short ACC_FINAL = 0x0010;
|
||||
final static short ACC_SYNCHRONIZED = 0x0020;
|
||||
final static short ACC_NATIVE = 0x0100;
|
||||
final static short ACC_ABSTRACT = 0x0400;
|
||||
|
||||
private UTF8Constant name;
|
||||
private UTF8Constant descriptor;
|
||||
|
||||
private short accessFlags;
|
||||
|
||||
private ClassFile classFile;
|
||||
|
||||
private Attribute[] attributes;
|
||||
|
||||
/**
|
||||
* <p> construct a descriptor for a method </p>
|
||||
*
|
||||
* @param method the name of the method
|
||||
* @param desc a type descriptor for its signature
|
||||
* @param flags access flags
|
||||
* @param cf the class file
|
||||
* @param attrs arbitrary attributes
|
||||
*
|
||||
*/
|
||||
|
||||
MethodDesc(String method, String desc, short flags, ClassFile cf, Attribute[] attrs) {
|
||||
super();
|
||||
|
||||
// we would validate here ...
|
||||
|
||||
name = new UTF8Constant(method, cf);
|
||||
descriptor = new UTF8Constant(desc, cf);
|
||||
accessFlags = flags;
|
||||
classFile = cf;
|
||||
attributes = attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the method to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeShort(accessFlags);
|
||||
dos.writeShort(name.getConstantPoolIndex());
|
||||
dos.writeShort(descriptor.getConstantPoolIndex());
|
||||
|
||||
if (attributes != null && attributes.length > 0) {
|
||||
dos.writeShort(attributes.length);
|
||||
|
||||
for (int i = 0; i < attributes.length; i++) {
|
||||
attributes[i].write(dos);
|
||||
}
|
||||
} else dos.writeShort(0);
|
||||
}
|
||||
}
|
115
src/FESI/ClassFile/NameAndTypeConstant.java
Normal file
115
src/FESI/ClassFile/NameAndTypeConstant.java
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
*
|
||||
* @(#) NameAndTypeConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.NameAndTypeConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
import FESI.ClassFile.UTF8Constant;
|
||||
|
||||
/**
|
||||
* <p> this class provides minimal support for NAME_AND_TYPE CPE's </p>
|
||||
*/
|
||||
|
||||
class NameAndTypeConstant extends ConstantPoolEntry {
|
||||
|
||||
private UTF8Constant name;
|
||||
private UTF8Constant desc;
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_NAMEANDTYPE CPE </p>
|
||||
*
|
||||
* @param n the name
|
||||
* @param d the type
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
NameAndTypeConstant(String n, String d, ClassFile cf) {
|
||||
super(CONSTANT_NAMEANDTYPE, cf);
|
||||
|
||||
name = new UTF8Constant(n, cf);
|
||||
desc = new UTF8Constant(d, cf);
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the CPE to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
|
||||
if (debug()) {
|
||||
System.err.println(getConstantPoolIndex() +
|
||||
" NAME: " +
|
||||
name.getConstantPoolIndex() +
|
||||
" TYPE: " +
|
||||
desc.getConstantPoolIndex()
|
||||
);
|
||||
}
|
||||
|
||||
dos.writeByte(getTag());
|
||||
dos.writeShort(name.getConstantPoolIndex());
|
||||
dos.writeShort(desc.getConstantPoolIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name string
|
||||
*/
|
||||
|
||||
String getName() { return name.getString(); }
|
||||
|
||||
/**
|
||||
* @return the type descriptor string
|
||||
*/
|
||||
|
||||
String getDescriptor() { return desc.getString(); }
|
||||
|
||||
/**
|
||||
* @return object equality
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof String) {
|
||||
return name.getString().equals(o) ||
|
||||
desc.getString().equals(o);
|
||||
} else if (o instanceof NameAndTypeConstant) {
|
||||
NameAndTypeConstant nandt = (NameAndTypeConstant)o;
|
||||
|
||||
return name.equals(nandt.getName()) &&
|
||||
desc.equals(nandt.getDescriptor());
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
112
src/FESI/ClassFile/RefConstant.java
Normal file
112
src/FESI/ClassFile/RefConstant.java
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
*
|
||||
* @(#) RefConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.RefConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
import FESI.ClassFile.ClassConstant;
|
||||
import FESI.ClassFile.NameAndTypeConstant;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* this base class provides minimal support for METHODREF, FIELDREF, and
|
||||
* INTERFACEMETHODREF CPE's
|
||||
* </p>
|
||||
*/
|
||||
|
||||
class RefConstant extends ConstantPoolEntry {
|
||||
|
||||
private ClassConstant clazz;
|
||||
private NameAndTypeConstant nandt;
|
||||
|
||||
/**
|
||||
* <p> construct a CPE </p>
|
||||
*
|
||||
* @param t the CPE tag value
|
||||
* @param cName the class name
|
||||
* @param nName the name of the referenced field or method
|
||||
* @param tName the type descriptor of the field or method
|
||||
* @param cf the class file
|
||||
*
|
||||
*/
|
||||
|
||||
protected RefConstant(byte t, String cName,
|
||||
String nName, String tName, ClassFile cf) {
|
||||
super(t, cf);
|
||||
|
||||
clazz = new ClassConstant(cName, cf);
|
||||
nandt = new NameAndTypeConstant(nName, tName, cf);
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the referenced object to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeByte(getTag());
|
||||
dos.writeShort(clazz.getConstantPoolIndex());
|
||||
dos.writeShort(nandt.getConstantPoolIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the class constant for the referenced object
|
||||
*/
|
||||
|
||||
ClassConstant getClassObject() { return clazz; }
|
||||
|
||||
/**
|
||||
* @return the name and type CPE for the referenced object
|
||||
*/
|
||||
|
||||
NameAndTypeConstant getNameAndType() { return nandt; }
|
||||
|
||||
/**
|
||||
* @return object equality
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof String) {
|
||||
return ((String)o).equals(nandt.getName());
|
||||
} else if (o instanceof RefConstant) {
|
||||
RefConstant rc = (RefConstant)o;
|
||||
|
||||
return clazz.equals(rc.getClassObject()) &&
|
||||
nandt.equals(rc.getNameAndType());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
105
src/FESI/ClassFile/StringConstant.java
Normal file
105
src/FESI/ClassFile/StringConstant.java
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
*
|
||||
* @(#) StringConstant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.StringConstant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
import FESI.ClassFile.UTF8Constant;
|
||||
|
||||
/**
|
||||
* <p> this class provides minimal support for CONSTANT_STRING CPE's <p>
|
||||
*/
|
||||
|
||||
final class StringConstant extends ConstantPoolEntry {
|
||||
|
||||
private UTF8Constant string;
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_STRING CPE </p>
|
||||
*
|
||||
* @param str the constant
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
StringConstant(String str, ClassFile cf) {
|
||||
super(CONSTANT_STRING, cf);
|
||||
|
||||
string = new UTF8Constant(str, cf);
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_STRING CPE </p>
|
||||
*
|
||||
* @param utf8 the utf8 constant
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
StringConstant(UTF8Constant utf8, ClassFile cf) {
|
||||
super(CONSTANT_STRING, cf);
|
||||
|
||||
string = utf8;
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the constant to the stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeByte(getTag());
|
||||
dos.writeShort(string.getConstantPoolIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the string constant
|
||||
*/
|
||||
|
||||
String getString() { return string.getString(); }
|
||||
|
||||
/**
|
||||
* @return object equality
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof String) {
|
||||
return string.equals(o);
|
||||
} else if (o instanceof StringConstant) {
|
||||
return string.equals(((StringConstant)o).getString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
89
src/FESI/ClassFile/UTF8Constant.java
Normal file
89
src/FESI/ClassFile/UTF8Constant.java
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
*
|
||||
* @(#) UTF8Constant.java 1.2@(#)
|
||||
*
|
||||
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
|
||||
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
|
||||
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
|
||||
* THIS SOFTWARE OR ITS DERIVATIVES.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* FESI.ClassFile.UTF8Constant
|
||||
* </p>
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Laurence P. G. Cable
|
||||
*/
|
||||
|
||||
|
||||
package FESI.ClassFile;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import FESI.ClassFile.ClassFile;
|
||||
import FESI.ClassFile.ConstantPoolEntry;
|
||||
|
||||
/**
|
||||
* <p> this class provides minimal support for CONSTANT_UTF8 CPE's </p>
|
||||
*/
|
||||
|
||||
class UTF8Constant extends ConstantPoolEntry {
|
||||
|
||||
private String string;
|
||||
|
||||
/**
|
||||
* <p> construct a CONSTANT_UTF8 CPE </p>
|
||||
*
|
||||
* @param s the string
|
||||
* @param cf the class file
|
||||
*/
|
||||
|
||||
UTF8Constant(String s, ClassFile cf) {
|
||||
super(CONSTANT_UTF8, cf);
|
||||
|
||||
string = s;
|
||||
|
||||
addToConstantPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> write the CPE to the output stream </p>
|
||||
*
|
||||
* @param dos the output stream
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
|
||||
void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeByte(getTag());
|
||||
dos.writeUTF(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the string constant
|
||||
*/
|
||||
|
||||
String getString() { return string; }
|
||||
|
||||
/**
|
||||
* @return object equality
|
||||
*/
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof String) {
|
||||
return string.equals((String)o);
|
||||
} else if (o instanceof UTF8Constant) {
|
||||
return string.equals(((UTF8Constant)o).getString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue