001    package serp.bytecode;
002    
003    import serp.bytecode.visitor.*;
004    
005    /**
006     * Loads a value from an array onto the stack.
007     *
008     * @author Abe White
009     */
010    public class ArrayLoadInstruction extends ArrayInstruction {
011        private static final Class[][] _mappings = new Class[][] {
012            { boolean.class, int.class },
013            { void.class, int.class },
014        };
015    
016        ArrayLoadInstruction(Code owner) {
017            super(owner);
018        }
019    
020        ArrayLoadInstruction(Code owner, int opcode) {
021            super(owner, opcode);
022        }
023    
024        public int getLogicalStackChange() {
025            switch (getOpcode()) {
026            case Constants.NOP:
027                return 0;
028            default:
029                return -1;
030            }
031        }
032    
033        public int getStackChange() {
034            switch (getOpcode()) {
035            case Constants.DALOAD:
036            case Constants.LALOAD:
037            case Constants.NOP:
038                return 0;
039            default:
040                return -1;
041            }
042        }
043    
044        public String getTypeName() {
045            switch (getOpcode()) {
046            case Constants.IALOAD:
047                return int.class.getName();
048            case Constants.LALOAD:
049                return long.class.getName();
050            case Constants.FALOAD:
051                return float.class.getName();
052            case Constants.DALOAD:
053                return double.class.getName();
054            case Constants.AALOAD:
055                return Object.class.getName();
056            case Constants.BALOAD:
057                return byte.class.getName();
058            case Constants.CALOAD:
059                return char.class.getName();
060            case Constants.SALOAD:
061                return short.class.getName();
062            default:
063                return null;
064            }
065        }
066    
067        public TypedInstruction setType(String type) {
068            type = mapType(type, _mappings, true);
069            if (type == null)
070                return (TypedInstruction) setOpcode(Constants.NOP);
071    
072            switch (type.charAt(0)) {
073            case 'i':
074                return (TypedInstruction) setOpcode(Constants.IALOAD);
075            case 'l':
076                return (TypedInstruction) setOpcode(Constants.LALOAD);
077            case 'f':
078                return (TypedInstruction) setOpcode(Constants.FALOAD);
079            case 'd':
080                return (TypedInstruction) setOpcode(Constants.DALOAD);
081            case 'b':
082                return (TypedInstruction) setOpcode(Constants.BALOAD);
083            case 'c':
084                return (TypedInstruction) setOpcode(Constants.CALOAD);
085            case 's':
086                return (TypedInstruction) setOpcode(Constants.SALOAD);
087            default:
088                return (TypedInstruction) setOpcode(Constants.AALOAD);
089            }
090        }
091    
092        public void acceptVisit(BCVisitor visit) {
093            visit.enterArrayLoadInstruction(this);
094            visit.exitArrayLoadInstruction(this);
095        }
096    }