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 }