001    package serp.bytecode.lowlevel;
002    
003    import java.io.DataInput;
004    import java.io.DataOutput;
005    import java.io.IOException;
006    
007    import serp.bytecode.visitor.BCVisitor;
008    
009    /**
010     * MethodHandle
011     *   u1 tag 
012     *   u1 reference_kind 
013     *   u2 reference_index
014     *
015     */
016    public class MethodHandleEntry extends Entry {
017        private int _reference_kind = 0;
018        private int _reference_index = 0;
019        
020        public MethodHandleEntry() {
021    
022        }
023    
024        public MethodHandleEntry(int _reference_kind, int _reference_index) {
025            this._reference_kind = _reference_kind;
026            this._reference_index = _reference_index;
027        }
028    
029        public void acceptVisit(BCVisitor visitor) {
030            visitor.enterMethodHandleEntry(this);
031            visitor.exitMethodHandleEntry(this);
032        }
033    
034        public int getType() {
035            return Entry.METHODHANDLE;
036        }
037    
038        void readData(DataInput in) throws IOException {
039            _reference_kind = in.readUnsignedByte();
040            _reference_index = in.readUnsignedShort();
041        }
042    
043        void writeData(DataOutput out) throws IOException {
044            out.writeByte(_reference_kind);
045            out.writeShort(_reference_index);
046        }
047        
048        public int getReferenceKind() {
049            return _reference_kind;
050        }
051        
052        public void setReferenceKind(int referenceKind) throws IllegalArgumentException {
053            if (referenceKind < 1 || referenceKind > 9) {
054                throw new IllegalArgumentException("MethodHandle referencekind cannot accept a value of " + referenceKind);
055            }
056            
057            _reference_kind = referenceKind;
058        }
059        
060        /**
061         * The Entry Type depends on both the reference kind and the Class Version (CV).
062         * 
063         * 1 (REF_getField), 2 (REF_getStatic), 3 (REF_putField), or 4 (REF_putStatic) - CONSTANT_Fieldref_info
064         * 5 (REF_invokeVirtual) or 8 (REF_newInvokeSpecial) - CONSTANT_Methodref_info
065         * 6 (REF_invokeStatic) or 7 (REF_invokeSpecial) 
066         *    - If CV < 52:  CONSTANT_Methodref_info
067         *    - if CV >= 52: CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info
068         * 9 (REF_invokeInterface) - CONSTANT_InterfaceMethodref_info
069         * 
070         * @return
071         */
072        public Entry getReference() {
073            return getPool().getEntry(_reference_index);
074        }
075        
076        public void setReference(int referenceIndex) {
077            _reference_index = referenceIndex;
078        }
079    
080    }