001    package serp.bytecode;
002    
003    import serp.bytecode.visitor.*;
004    
005    /**
006     * Store a value from the stack into an array.
007     *
008     * @author Abe White
009     */
010    public class ArrayStoreInstruction extends ArrayInstruction {
011        private static final Class[][] _mappings = new Class[][] {
012            { boolean.class, int.class },
013            { void.class, int.class },
014        };
015    
016        ArrayStoreInstruction(Code owner) {
017            super(owner);
018        }
019    
020        ArrayStoreInstruction(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 -3;
030            }
031        }
032    
033        public int getStackChange() {
034            switch (getOpcode()) {
035            case Constants.DASTORE:
036            case Constants.LASTORE:
037                return -4;
038            case Constants.NOP:
039                return 0;
040            default:
041                return -3;
042            }
043        }
044    
045        public String getTypeName() {
046            switch (getOpcode()) {
047            case Constants.IASTORE:
048                return int.class.getName();
049            case Constants.LASTORE:
050                return long.class.getName();
051            case Constants.FASTORE:
052                return float.class.getName();
053            case Constants.DASTORE:
054                return double.class.getName();
055            case Constants.AASTORE:
056                return Object.class.getName();
057            case Constants.BASTORE:
058                return byte.class.getName();
059            case Constants.CASTORE:
060                return char.class.getName();
061            case Constants.SASTORE:
062                return short.class.getName();
063            default:
064                return null;
065            }
066        }
067    
068        public TypedInstruction setType(String type) {
069            type = mapType(type, _mappings, true);
070            if (type == null)
071                return (TypedInstruction) setOpcode(Constants.NOP);
072    
073            switch (type.charAt(0)) {
074            case 'i':
075                return (TypedInstruction) setOpcode(Constants.IASTORE);
076            case 'l':
077                return (TypedInstruction) setOpcode(Constants.LASTORE);
078            case 'f':
079                return (TypedInstruction) setOpcode(Constants.FASTORE);
080            case 'd':
081                return (TypedInstruction) setOpcode(Constants.DASTORE);
082            case 'b':
083                return (TypedInstruction) setOpcode(Constants.BASTORE);
084            case 'c':
085                return (TypedInstruction) setOpcode(Constants.CASTORE);
086            case 's':
087                return (TypedInstruction) setOpcode(Constants.SASTORE);
088            default:
089                return (TypedInstruction) setOpcode(Constants.AASTORE);
090            }
091        }
092    
093        public void acceptVisit(BCVisitor visit) {
094            visit.enterArrayStoreInstruction(this);
095            visit.exitArrayStoreInstruction(this);
096        }
097    }