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 }