001package serp.bytecode;
002
003import serp.bytecode.visitor.*;
004
005/**
006 * Store a value from the stack into an array.
007 *
008 * @author Abe White
009 */
010public 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}