All Downloads are FREE. Search and download functionalities are using the official Maven repository.

serp.bytecode.lowlevel.Entry Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
package serp.bytecode.lowlevel;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import serp.bytecode.visitor.VisitAcceptor;

/**
 * Base type for all constant pool entries. Entries should generally be
 * considered immutable; modifying an entry directly can have dire
 * consequences, and often renders the resulting class file invalid.
 *
 * 

Entries cannot be shared among constant pools.

* * @author Abe White */ public abstract class Entry implements VisitAcceptor { public static final int UTF8 = 1; public static final int INT = 3; public static final int FLOAT = 4; public static final int LONG = 5; public static final int DOUBLE = 6; public static final int CLASS = 7; public static final int STRING = 8; public static final int FIELD = 9; public static final int METHOD = 10; public static final int INTERFACEMETHOD = 11; public static final int NAMEANDTYPE = 12; public static final int METHODHANDLE = 15; public static final int METHODTYPE = 16; public static final int INVOKEDYNAMIC = 18; private ConstantPool _pool = null; private int _index = 0; /** * Read a single entry from the given bytecode stream and returns it. */ public static Entry read(DataInput in) throws IOException { Entry entry = create(in.readUnsignedByte()); entry.readData(in); return entry; } /** * Write the given entry to the given bytecode stream. */ public static void write(Entry entry, DataOutput out) throws IOException { out.writeByte(entry.getType()); entry.writeData(out); } /** * Create an entry based on its type code. */ public static Entry create(int type) { switch (type) { case CLASS: return new ClassEntry(); case FIELD: return new FieldEntry(); case METHOD: return new MethodEntry(); case INTERFACEMETHOD: return new InterfaceMethodEntry(); case STRING: return new StringEntry(); case INT: return new IntEntry(); case FLOAT: return new FloatEntry(); case LONG: return new LongEntry(); case DOUBLE: return new DoubleEntry(); case NAMEANDTYPE: return new NameAndTypeEntry(); case UTF8: return new UTF8Entry(); case METHODHANDLE: return new MethodHandleEntry(); case METHODTYPE: return new MethodTypeEntry(); case INVOKEDYNAMIC: return new InvokeDynamicEntry(); default: throw new IllegalArgumentException("type = " + type); } } /** * Return the type code for this entry type. */ public abstract int getType(); /** * Return true if this is a wide entry -- i.e. if it takes up two * places in the constant pool. Returns false by default. */ public boolean isWide() { return false; } /** * Returns the constant pool containing this entry, or null if none. */ public ConstantPool getPool() { return _pool; } /** * Returns the index of the entry in the owning constant pool, or 0. */ public int getIndex() { return _index; } /** * This method is called after reading the entry type from bytecode. * It should read all the data for this entry from the given stream. */ abstract void readData(DataInput in) throws IOException; /** * This method is called after writing the entry type to bytecode. * It should write all data for this entry to the given stream. */ abstract void writeData(DataOutput out) throws IOException; /** * Subclasses must call this method before their state is mutated. */ Object beforeModify() { if (_pool == null) return null; return _pool.getKey(this); } /** * Subclasses must call this method when their state is mutated. */ void afterModify(Object key) { if (_pool != null) _pool.modifyEntry(key, this); } /** * Sets the owning pool of the entry. */ void setPool(ConstantPool pool) { // attempting to overwrite current pool? if (_pool != null && pool != null && _pool != pool) throw new IllegalStateException("Entry already belongs to a pool"); _pool = pool; } /** * Set the index of this entry within the pool. */ void setIndex(int index) { _index = index; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy