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    }