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:
hns 2000-12-29 17:58:10 +00:00
parent af35ca5581
commit ee13186158
148 changed files with 34934 additions and 0 deletions

View 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);
}

View 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;
}
}

View 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) + ";";
}
}

View 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);
}
}

View 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(); }
}

View 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);
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}