00001 package de.fub.bytecode.generic;
00002
00003 import java.io.*;
00004 import de.fub.bytecode.util.ByteSequence;
00005 import de.fub.bytecode.classfile.Utility;
00006 import de.fub.bytecode.Constants;
00007
00008
00009
00010
00011
00012
00013
00014 public abstract class LocalVariableInstruction extends Instruction
00015 implements TypedInstruction, IndexedInstruction {
00016 private int n;
00017 private short c_tag;
00018 private short canon_tag;
00019
00020
00021
00022
00023
00024
00025 LocalVariableInstruction(short canon_tag, short c_tag) {
00026 super();
00027 this.canon_tag = canon_tag;
00028 this.c_tag = c_tag;
00029 }
00030
00031
00032
00033
00034
00035 protected LocalVariableInstruction(short tag, short c_tag, int n) {
00036 super(tag, (short)2);
00037
00038 this.c_tag = c_tag;
00039 canon_tag = tag;
00040
00041 setIndex(n);
00042 }
00043
00044
00045
00046
00047 public void dump(DataOutputStream out) throws IOException {
00048 if(wide())
00049 out.writeByte(Constants.WIDE);
00050
00051 out.writeByte(tag);
00052
00053 if(length > 1) {
00054 if(wide())
00055 out.writeShort(n);
00056 else
00057 out.writeByte(n);
00058 }
00059 }
00060
00061
00062 public short getCanonicalTag() {
00063 return canon_tag;
00064 }
00065
00066
00067
00068 public final int getIndex() { return n; }
00069
00070
00071 public Type getType(ConstantPoolGen cp) {
00072 switch(canon_tag) {
00073 case Constants.ILOAD: case Constants.ISTORE:
00074 return Type.INT;
00075 case Constants.LLOAD: case Constants.LSTORE:
00076 return Type.LONG;
00077 case Constants.DLOAD: case Constants.DSTORE:
00078 return Type.DOUBLE;
00079 case Constants.FLOAD: case Constants.FSTORE:
00080 return Type.FLOAT;
00081 case Constants.ALOAD: case Constants.ASTORE:
00082 return Type.OBJECT;
00083
00084 default: throw new ClassGenException("Oops: unknown case in switch" + canon_tag);
00085 }
00086 }
00087
00088
00089
00090
00091 protected void initFromFile(ByteSequence bytes, boolean wide)
00092 throws IOException
00093 {
00094 if(wide) {
00095 n = bytes.readUnsignedShort();
00096 length = 4;
00097 } else if(((tag >= Constants.ILOAD) &&
00098 (tag <= Constants.ALOAD)) ||
00099 ((tag >= Constants.ISTORE) &&
00100 (tag <= Constants.ASTORE))) {
00101 n = bytes.readUnsignedByte();
00102 length = 2;
00103 } else if(tag <= Constants.ALOAD_3) {
00104 n = (tag - Constants.ILOAD_0) % 4;
00105 length = 1;
00106 } else {
00107 n = (tag - Constants.ISTORE_0) % 4;
00108 length = 1;
00109 }
00110 }
00111
00112
00113
00114 public final void setIndex(int n) {
00115 if((n < 0) || (n > Constants.MAX_SHORT))
00116 throw new ClassGenException("Illegal value: " + n);
00117
00118 this.n = n;
00119
00120 if(n >= 0 && n <= 3) {
00121 tag = (short)(c_tag + n);
00122 length = 1;
00123 } else {
00124 tag = canon_tag;
00125
00126 if(wide())
00127 length = 4;
00128 else
00129 length = 2;
00130 }
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 public String toString(boolean verbose) {
00142 if(((tag >= Constants.ILOAD_0) &&
00143 (tag <= Constants.ALOAD_3)) ||
00144 ((tag >= Constants.ISTORE_0) &&
00145 (tag <= Constants.ASTORE_3)))
00146 return super.toString(verbose);
00147 else
00148 return super.toString(verbose) + " " + n;
00149 }
00150 private final boolean wide() { return n > Constants.MAX_BYTE; }
00151 }