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