1 package com.sun.org.apache.bcel.internal.generic; 2 3 56 57 import com.sun.org.apache.bcel.internal.Constants; 58 import com.sun.org.apache.bcel.internal.classfile.Utility; 59 import com.sun.org.apache.bcel.internal.classfile.ConstantPool; 60 import java.io.*; 61 import com.sun.org.apache.bcel.internal.util.ByteSequence; 62 63 69 public abstract class Instruction implements Cloneable , Serializable { 70 protected short length = 1; protected short opcode = -1; 73 77 Instruction() {} 78 79 public Instruction(short opcode, short length) { 80 this.length = length; 81 this.opcode = opcode; 82 } 83 84 88 public void dump(DataOutputStream out) throws IOException { 89 out.writeByte(opcode); } 91 92 101 public String toString(boolean verbose) { 102 if(verbose) 103 return Constants.OPCODE_NAMES[opcode] + "[" + opcode + "](" + length + ")"; 104 else 105 return Constants.OPCODE_NAMES[opcode]; 106 } 107 108 111 public String toString() { 112 return toString(true); 113 } 114 115 118 public String toString(ConstantPool cp) { 119 return toString(false); 120 } 121 122 130 public Instruction copy() { 131 Instruction i = null; 132 133 if(InstructionConstants.INSTRUCTIONS[this.getOpcode()] != null) 135 i = this; 136 else { 137 try { 138 i = (Instruction)clone(); 139 } catch(CloneNotSupportedException e) { 140 System.err.println(e); 141 } 142 } 143 144 return i; 145 } 146 147 153 protected void initFromFile(ByteSequence bytes, boolean wide) 154 throws IOException 155 {} 156 157 164 public static final Instruction readInstruction(ByteSequence bytes) 165 throws IOException 166 { 167 boolean wide = false; 168 short opcode = (short)bytes.readUnsignedByte(); 169 Instruction obj = null; 170 171 if(opcode == Constants.WIDE) { wide = true; 173 opcode = (short)bytes.readUnsignedByte(); 174 } 175 176 if(InstructionConstants.INSTRUCTIONS[opcode] != null) 177 return InstructionConstants.INSTRUCTIONS[opcode]; 179 182 Class clazz; 183 try { 184 clazz = Class.forName(className(opcode)); 185 } 186 catch (ClassNotFoundException cnfe){ 187 throw new ClassGenException("Illegal opcode detected."); 190 } 191 try { 192 obj = (Instruction)clazz.newInstance(); 193 194 if(wide && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || 195 (obj instanceof RET))) 196 throw new Exception ("Illegal opcode after wide: " + opcode); 197 198 obj.setOpcode(opcode); 199 obj.initFromFile(bytes, wide); } catch(Exception e) { throw new ClassGenException(e.toString()); } 202 203 return obj; 204 } 205 206 private static final String className(short opcode) { 207 String name = Constants.OPCODE_NAMES[opcode].toUpperCase(); 208 209 212 try { 213 int len = name.length(); 214 char ch1 = name.charAt(len - 2), ch2 = name.charAt(len - 1); 215 216 if((ch1 == '_') && (ch2 >= '0') && (ch2 <= '5')) 217 name = name.substring(0, len - 2); 218 219 if(name.equals("ICONST_M1")) name = "ICONST"; 221 } catch(StringIndexOutOfBoundsException e) { System.err.println(e); } 222 223 return "com.sun.org.apache.bcel.internal.generic." + name; 224 } 225 226 233 public int consumeStack(ConstantPoolGen cpg) { 234 return Constants.CONSUME_STACK[opcode]; 235 } 236 237 244 public int produceStack(ConstantPoolGen cpg) { 245 return Constants.PRODUCE_STACK[opcode]; 246 } 247 248 251 public short getOpcode() { return opcode; } 252 253 256 public int getLength() { return length; } 257 258 261 private void setOpcode(short opcode) { this.opcode = opcode; } 262 263 265 void dispose() { } 266 267 275 public abstract void accept(Visitor v); 276 } 277 | Popular Tags |