serp.bytecode.ClassInstruction Maven / Gradle / Ivy
package serp.bytecode;
import java.io.*;
import serp.bytecode.lowlevel.*;
import serp.bytecode.visitor.*;
/**
* An instruction that takes as an argument a class to operate
* on. Examples include anewarray, checkcast, instance, anew
, etc.
*
* @author Abe White
*/
public class ClassInstruction extends TypedInstruction {
private int _index = 0;
ClassInstruction(Code owner, int opcode) {
super(owner, opcode);
}
public int getStackChange() {
if (getOpcode() == Constants.NEW)
return 1;
return 0;
}
int getLength() {
return super.getLength() + 2;
}
/**
* Return the {@link ConstantPool} index of the
* {@link ClassEntry} describing the class for this instruction.
*/
public int getTypeIndex() {
return _index;
}
/**
* Set the {@link ConstantPool} index of the
* {@link ClassEntry} describing the class for this instruction.
*
* @return this instruction, for method chaining
*/
public ClassInstruction setTypeIndex(int index) {
_index = index;
return this;
}
public String getTypeName() {
if (_index == 0)
return null;
ClassEntry entry = (ClassEntry) getPool().getEntry(_index);
return getProject().getNameCache().getExternalForm(entry.
getNameEntry().getValue(), false);
}
public TypedInstruction setType(String type) {
if (type == null)
_index = 0;
else {
type = getProject().getNameCache().getInternalForm(type, false);
_index = getPool().findClassEntry(type, true);
}
return this;
}
/**
* ClassInstructions are equal if the type they reference is the same or
* unset and if their opcodes are equal.
*/
public boolean equalsInstruction(Instruction other) {
if (other == this)
return true;
if (!super.equalsInstruction(other))
return false;
String type = getTypeName();
String otherType = ((ClassInstruction) other).getTypeName();
return (type == null) || (otherType == null) || type.equals(otherType);
}
public void acceptVisit(BCVisitor visit) {
visit.enterClassInstruction(this);
visit.exitClassInstruction(this);
}
void read(Instruction other) {
super.read(other);
setType(((ClassInstruction) other).getTypeName());
}
void read(DataInput in) throws IOException {
super.read(in);
_index = in.readUnsignedShort();
}
void write(DataOutput out) throws IOException {
super.write(out);
out.writeShort(_index);
}
}