001 package sysModel.classFile.code.instructions;
002
003 import sysModel.classFile.code.Opcode;
004 import sysModel.classFile.Types;
005
006 /**
007 * Instruction containing a reference to the constant pool.
008 *
009 * @author Mathias
010 */
011 public class ReferenceInstruction extends GenericInstruction {
012 /**
013 * Constructor.
014 *
015 * @param opcode invoke opcode
016 * @param constantPoolId method id in constant pool
017 */
018 public ReferenceInstruction(byte opcode, short constantPoolId) {
019 super(new byte[]{Opcode.NOP});
020
021 switch(opcode) {
022 case Opcode.INVOKESTATIC:
023 case Opcode.INVOKESPECIAL:
024 case Opcode.INVOKEVIRTUAL:
025 case Opcode.CHECKCAST:
026 case Opcode.GETFIELD:
027 case Opcode.GETSTATIC:
028 case Opcode.INSTANCEOF:
029 case Opcode.NEW:
030 case Opcode.PUTFIELD:
031 case Opcode.PUTSTATIC:
032 case Opcode.ANEWARRAY:
033 case Opcode.NEWARRAY:
034 case Opcode.LDC_W:
035 case Opcode.LDC2_W:
036 break;
037 default:
038 throw new IllegalArgumentException("Illegal reference instruction: " + Opcode.getOpcodeName(opcode));
039 }
040
041 _code = new byte[3];
042 _code[0] = opcode;
043 setReference(constantPoolId);
044 }
045
046 /**
047 * Make a new generic instruction from the bytecode stating at pc, padded using paddingPC, and use the line number
048 * table for branches.
049 *
050 * @param bytecode bytecode
051 * @param pc starting index in bytecode
052 * @param paddingPC PC for padding
053 * @param lnt line number table for branches
054 */
055 public ReferenceInstruction(byte[] bytecode, short pc, short paddingPC, LineNumberTable lnt) {
056 super(bytecode, pc, paddingPC, lnt);
057 }
058
059 /**
060 * Set the constant pool id.
061 *
062 * @param constantPoolId new constant pool id
063 */
064 public void setReference(short constantPoolId) {
065 Types.bytesFromShort(constantPoolId, _code, 1);
066 }
067
068 /**
069 * Get the constant pool id.
070 *
071 * @return constant pool id
072 */
073 public short getReference() {
074 return Types.shortFromBytes(_code, 1);
075 }
076 }