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 }