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 }