0 Replies Latest reply on Jul 13, 2009 1:14 PM by tumbleweed

    Problem with branches and ldc/ldc_w

    tumbleweed

      Hello,

      i'm working with javassist for quite some time now and I must say it is really impressive what this thing can do, and with what ease!

      Anyways, I'm confronted with one problem:
      My tool inserts an arbitrary series of conditional branches and some code afterwards. This means I have to precalculate the number of bytes inserted for all following conditions and the code in respect to set the branch offset. All works well unless I load a string constant using addLdc(String). In this case I am unable to precalculate whether there are 3 bytes (ldc) or 4 bytes (ldc_w) inserted, since this depends on the ConstTables state at insertion time.

      I've developed a workaround for my case by extending the Bytecode class and altering its behaviour with

      private ArrayList<Integer> m_branches;
      ...
      
      public void addBranch(int code, int branchOffset) {
       // branch opcode is inserted at offset getSize()
       m_branches.add(getSize());
       addOpcode(code);
       add16bit(branchOffset);
      }
      
      private void adjustBranches(int end, int shift) {
       for (Integer pos : m_branches) {
       int branchOffset = read16bit(pos + 1);
       if ((pos + branchOffset) <= end) continue;
       write16bit(pos + 1, branchOffset + shift);
       }
      }
      
      @Override
      public void addLdc(int i) {
       if (i > 0xFF) {
       adjustBranches(getSize(), 1);
       addOpcode(LDC_W);
       addIndex(i);
       } else {
       addOpcode(LDC);
       add(i);
       }
      }
      


      I think this is could be extended to a general solution, if it would be well defined how many bytes one should asume to be inserted.

      Is there a way around this problem that I've overseen or is this really a "bug"?

      ---

      By the way, is there any reason there is no
      public void add16bit(int value) {
       value = value % 65536;
       add(value >> 8);
       add(value % 256);
      }
      

      defined in Bytecode? Since it is required for inserting branch offsets...