/** * Read an instruction from (byte code) input stream and return the appropiate object. * * @param file file to read from * @return instruction object being read */ public static final Instruction readInstruction(ByteSequence bytes) throws IOException { boolean wide = false; short opcode = (short) bytes.readUnsignedByte(); Instruction obj = null; if (opcode == Constants.WIDE) { // Read next opcode after wide byte wide = true; opcode = (short) bytes.readUnsignedByte(); } if (InstructionConstants.INSTRUCTIONS[opcode] != null) return InstructionConstants.INSTRUCTIONS[ opcode]; // Used predefined immutable object, if available /* Find appropiate class, instantiate an (empty) instruction object * and initialize it by hand. */ Class clazz; try { clazz = Class.forName(className(opcode)); } catch (ClassNotFoundException cnfe) { // If a class by that name does not exist, the opcode is illegal. // Note that IMPDEP1, IMPDEP2, BREAKPOINT are also illegal in a sense. throw new ClassGenException("Illegal opcode detected."); } try { obj = (Instruction) clazz.newInstance(); if (wide && !((obj instanceof LocalVariableInstruction) || (obj instanceof IINC) || (obj instanceof RET))) throw new Exception("Illegal opcode after wide: " + opcode); obj.setOpcode(opcode); obj.initFromFile(bytes, wide); // Do further initializations, if any // Byte code offset set in InstructionList } catch (Exception e) { throw new ClassGenException(e.toString()); } return obj; }
/** Read needed data (e.g. index) from file. */ protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException { length = 3; b = bytes.readShort(); }