Example #1
0
 /**
  * Initialize instruction list from byte array.
  *
  * @param code byte array containing the instructions
  */
 public InstructionList(byte[] code) {
   ByteSequence bytes = new ByteSequence(code);
   InstructionHandle[] ihs = new InstructionHandle[code.length];
   int[] pos = new int[code.length]; // Can't be more than that
   int count = 0; // Contains actual length
   /* Pass 1: Create an object for each byte code and append them
    * to the list.
    */
   try {
     while (bytes.available() > 0) {
       // Remember byte offset and associate it with the instruction
       int off = bytes.getIndex();
       pos[count] = off;
       /* Read one instruction from the byte stream, the byte position is set
        * accordingly.
        */
       Instruction i = Instruction.readInstruction(bytes);
       InstructionHandle ih;
       if (i instanceof BranchInstruction) {
         ih = append((BranchInstruction) i);
       } else {
         ih = append(i);
       }
       ih.setPosition(off);
       ihs[count] = ih;
       count++;
     }
   } catch (IOException e) {
     throw new ClassGenException(e.toString(), e);
   }
   byte_positions = new int[count]; // Trim to proper size
   System.arraycopy(pos, 0, byte_positions, 0, count);
   /* Pass 2: Look for BranchInstruction and update their targets, i.e.,
    * convert offsets to instruction handles.
    */
   for (int i = 0; i < count; i++) {
     if (ihs[i] instanceof BranchHandle) {
       BranchInstruction bi = (BranchInstruction) ihs[i].instruction;
       int target = bi.position + bi.getIndex(); /* Byte code position:
                * relative -> absolute. */
       // Search for target position
       InstructionHandle ih = findHandle(ihs, pos, count, target);
       if (ih == null) {
         throw new ClassGenException("Couldn't find target for branch: " + bi);
       }
       bi.setTarget(ih); // Update target
       // If it is a Select instruction, update all branch targets
       if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
         Select s = (Select) bi;
         int[] indices = s.getIndices();
         for (int j = 0; j < indices.length; j++) {
           target = bi.position + indices[j];
           ih = findHandle(ihs, pos, count, target);
           if (ih == null) {
             throw new ClassGenException("Couldn't find target for switch: " + bi);
           }
           s.setTarget(j, ih); // Update target
         }
       }
     }
   }
 }