0 Replies Latest reply on Jun 11, 2010 9:09 PM by alasdair

    Problem with CodeIterator.newOffset()

      I've been having some problems with Javassist which I think I've finally narrowed down to the way that "goto" offsets are updated when you insert new bytecode. It looks as though newOffset is not correctly handling the case when you insert new opcodes at a location which already contains a "goto" opcode.
          private static int newOffset(int i, int offset, int where,
                                       int gapLength, boolean exclusive) {
              int target = i + offset;
              if (i < where) {
                  if (where < target || (exclusive && where == target))
                      offset += gapLength;
              }
              else if (i == where) {
                  if (target < where && exclusive)
                      offset -= gapLength;
                  else if (where < target && !exclusive)
                      offset += gapLength;
              }
              else
                  if (target < where || (!exclusive && where == target))
                      offset -= gapLength;
              return offset;
          }
      And I think the middle clause should look like this:
              else if (i == where) {
                  if (target < where)
                      offset -= gapLength;
              }
      If you insert new bytecode at a location containing a goto (so that the goto opcode is about to be moved forward by n bytes) then you need to modify the offset if it's negative, but keep it the same if it's already positive.
      I've made this change and re-run the tests, which all pass, but I wanted to check to see if this fix looks reasonable.
      I don't have a simple test case that shows the problem. I found this when I tried to run my testing framework ThreadWeaver (http://code.google.com/p/thread-weaver/) with the latest version of Javassist. The problem can be demonstrated by building ThreadWeaver and running the unit tests.
      If you want a simpler test case let me know. I think THreadWeaver triggered this because it uses Javassist to insert lots of small code snippets into the instrumented bytecode.
      Alasdair