001 package serp.bytecode; 002 003 import java.io.*; 004 import java.util.*; 005 006 import serp.bytecode.visitor.*; 007 008 /** 009 * Returns a value (or void) from a method. 010 * 011 * @author Abe White 012 */ 013 public class ReturnInstruction extends TypedInstruction { 014 private static final Class[][] _mappings = new Class[][] { 015 { byte.class, int.class }, 016 { char.class, int.class }, 017 { short.class, int.class }, 018 { boolean.class, int.class }, 019 }; 020 021 ReturnInstruction(Code owner) { 022 super(owner); 023 } 024 025 ReturnInstruction(Code owner, int opcode) { 026 super(owner, opcode); 027 } 028 029 public String getTypeName() { 030 switch (getOpcode()) { 031 case Constants.IRETURN: 032 return int.class.getName(); 033 case Constants.LRETURN: 034 return long.class.getName(); 035 case Constants.FRETURN: 036 return float.class.getName(); 037 case Constants.DRETURN: 038 return double.class.getName(); 039 case Constants.ARETURN: 040 return Object.class.getName(); 041 case Constants.RETURN: 042 return void.class.getName(); 043 default: 044 return null; 045 } 046 } 047 048 public TypedInstruction setType(String type) { 049 type = mapType(type, _mappings, true); 050 if (type == null) 051 return (TypedInstruction) setOpcode(Constants.NOP); 052 053 switch (type.charAt(0)) { 054 case 'i': 055 return (TypedInstruction) setOpcode(Constants.IRETURN); 056 case 'l': 057 return (TypedInstruction) setOpcode(Constants.LRETURN); 058 case 'f': 059 return (TypedInstruction) setOpcode(Constants.FRETURN); 060 case 'd': 061 return (TypedInstruction) setOpcode(Constants.DRETURN); 062 case 'v': 063 return (TypedInstruction) setOpcode(Constants.RETURN); 064 default: 065 return (TypedInstruction) setOpcode(Constants.ARETURN); 066 } 067 } 068 069 public int getLogicalStackChange() { 070 switch (getOpcode()) { 071 case Constants.NOP: 072 return 0; 073 default: 074 return -1; 075 } 076 } 077 078 public int getStackChange() { 079 switch (getOpcode()) { 080 case Constants.RETURN: 081 case Constants.NOP: 082 return 0; 083 case Constants.LRETURN: 084 case Constants.DRETURN: 085 return -2; 086 default: 087 return -1; 088 } 089 } 090 091 public void acceptVisit(BCVisitor visit) { 092 visit.enterReturnInstruction(this); 093 visit.exitReturnInstruction(this); 094 } 095 }