コード例 #1
0
 /** @return complete, i.e., deep copy of this list */
 public InstructionList copy() {
   Map<InstructionHandle, InstructionHandle> map =
       new HashMap<InstructionHandle, InstructionHandle>();
   InstructionList il = new InstructionList();
   /* Pass 1: Make copies of all instructions, append them to the new list
    * and associate old instruction references with the new ones, i.e.,
    * a 1:1 mapping.
    */
   for (InstructionHandle ih = start; ih != null; ih = ih.next) {
     Instruction i = ih.instruction;
     Instruction c = i.copy(); // Use clone for shallow copy
     if (c instanceof BranchInstruction) {
       map.put(ih, il.append((BranchInstruction) c));
     } else {
       map.put(ih, il.append(c));
     }
   }
   /* Pass 2: Update branch targets.
    */
   InstructionHandle ih = start;
   InstructionHandle ch = il.start;
   while (ih != null) {
     Instruction i = ih.instruction;
     Instruction c = ch.instruction;
     if (i instanceof BranchInstruction) {
       BranchInstruction bi = (BranchInstruction) i;
       BranchInstruction bc = (BranchInstruction) c;
       InstructionHandle itarget = bi.getTarget(); // old target
       // New target is in hash map
       bc.setTarget(map.get(itarget));
       if (bi instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
         InstructionHandle[] itargets = ((Select) bi).getTargets();
         InstructionHandle[] ctargets = ((Select) bc).getTargets();
         for (int j = 0; j < itargets.length; j++) { // Update all targets
           ctargets[j] = map.get(itargets[j]);
         }
       }
     }
     ih = ih.next;
     ch = ch.next;
   }
   return il;
 }
コード例 #2
0
 /**
  * Redirect all references from old_target to new_target, i.e., update targets of branch
  * instructions.
  *
  * @param old_target the old target instruction handle
  * @param new_target the new target instruction handle
  */
 public void redirectBranches(InstructionHandle old_target, InstructionHandle new_target) {
   for (InstructionHandle ih = start; ih != null; ih = ih.next) {
     Instruction i = ih.getInstruction();
     if (i instanceof BranchInstruction) {
       BranchInstruction b = (BranchInstruction) i;
       InstructionHandle target = b.getTarget();
       if (target == old_target) {
         b.setTarget(new_target);
       }
       if (b instanceof Select) { // Either LOOKUPSWITCH or TABLESWITCH
         InstructionHandle[] targets = ((Select) b).getTargets();
         for (int j = 0; j < targets.length; j++) {
           if (targets[j] == old_target) {
             ((Select) b).setTarget(j, new_target);
           }
         }
       }
     }
   }
 }
コード例 #3
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
         }
       }
     }
   }
 }