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 }