001package serp.bytecode.lowlevel;
002
003import java.io.DataInput;
004import java.io.DataOutput;
005import java.io.IOException;
006
007import serp.bytecode.visitor.BCVisitor;
008
009/**
010 * MethodHandle
011 *   u1 tag 
012 *   u1 reference_kind 
013 *   u2 reference_index
014 *
015 */
016public 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}