]> source.dussan.org Git - javassist.git/commitdiff
fixed a bug of replace(String,ExprEditor) in javassist.expr.Expr.
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sun, 9 Apr 2006 15:11:11 +0000 (15:11 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sun, 9 Apr 2006 15:11:11 +0000 (15:11 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@267 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

Readme.html
src/main/javassist/bytecode/CodeIterator.java
src/main/javassist/expr/Expr.java
src/main/javassist/expr/ExprEditor.java

index ba4faf1add1e357858378043becc702d37f9de04..cc4317a5baced89d3ba7dda3bb6653d8a297681f 100644 (file)
@@ -281,6 +281,11 @@ see javassist.Dump.
 
 <h2>Changes</h2>
 
+<p>- version 3.2
+<ul>
+  <li>A bug of replace(String,ExprEditor) in javassist.expr.Expr has been fixed.
+</ul>
+
 <p>- version 3.2.0.CR1 on March 18, 2006
 <ul>
   <li>Annotations enhancements to javassist.bytecode.MethodInfo.
index 52b0a4a0152c28bcbd3a3604c6cf705dfbc03f30..13948c9153a42f662e9daa0b70d47cdbfeb7c0c1 100644 (file)
@@ -18,6 +18,11 @@ package javassist.bytecode;
 /**
  * An iterator for editing a code attribute.
  *
+ * <p>If there are multiple <code>CodeIterator</code>s referring to the
+ * same <code>Code_attribute</code>, then inserting a gap by one
+ * <code>CodeIterator</code> will break the other
+ * <code>CodeIterator</code>.
+ *
  * <p>This iterator does not provide <code>remove()</code>.
  * If a piece of code in a <code>Code_attribute</code> is unnecessary,
  * it should be overwritten with <code>NOP</code>.
@@ -30,7 +35,7 @@ public class CodeIterator implements Opcode {
     protected int endPos;
     protected int currentPos;
 
-    CodeIterator(CodeAttribute ca) {
+    protected CodeIterator(CodeAttribute ca) {
         codeAttr = ca;
         bytecode = ca.getCode();
         begin();
@@ -468,9 +473,21 @@ public class CodeIterator implements Opcode {
         codeAttr.setCode(c);
         bytecode = c;
         endPos = getCodeLength();
+        updateCursors(pos, length2);
         return length2;
     }
 
+    /**
+     * Is called when a gap is inserted.  The default implementation is empty.
+     * A subclass can override this method so that cursors will be updated.
+     *
+     * @param pos           the position where a gap is inserted.
+     * @param length        the length of the gap.
+     */
+    protected void updateCursors(int pos, int length) {
+        // empty
+    }
+
     /**
      * Copies and inserts the entries in the given exception table
      * at the beginning of the exception table in the code attribute
index c6cf78ebceaeff95330f5bf23ada8e2eb8a5e916..e2d455f271476954f8ca96febe1a6db6e7e80ba4 100644 (file)
@@ -301,14 +301,13 @@ public abstract class Expr implements Opcode {
         codeAttr.setMaxLocals(newLocals);
         ExprEditor.LoopContext context
             = new ExprEditor.LoopContext(newLocals);
-        CodeIterator iterator = codeAttr.iterator();
-        iterator.move(currentPos);
-        int size = iterator.getCodeLength();
+        int size = oldIterator.getCodeLength();
         int endPos = oldIterator.lookAhead();
-        if (ed.doit(thisClass, thisMethod, context, iterator, endPos))
+        oldIterator.move(currentPos);
+        if (ed.doit(thisClass, thisMethod, context, oldIterator, endPos))
             edited = true;
 
-        oldIterator.move(endPos + iterator.getCodeLength() - size);
+        oldIterator.move(endPos + oldIterator.getCodeLength() - size);
         codeAttr.setMaxLocals(orgLocals);
         codeAttr.setMaxStack(orgStack);
         maxLocals = context.maxLocals;
index a713dde39233636495c5caed579ce9deb1ed3590..743b8d2ff769b61b6ca5c402616b6284fb3c5753 100644 (file)
@@ -110,14 +110,19 @@ public class ExprEditor {
      * Visits each bytecode in the given range. 
      */
     boolean doit(CtClass clazz, MethodInfo minfo, LoopContext context,
-            CodeIterator iterator, int endPos)
+                 CodeIterator iterator, int endPos)
         throws CannotCompileException
     {
         boolean edited = false;
-
-        while (iterator.hasNext() && iterator.lookAhead() < endPos)
-            if (loopBody(iterator, clazz, minfo, context))
+        while (iterator.hasNext() && iterator.lookAhead() < endPos) {
+            int size = iterator.getCodeLength();
+            if (loopBody(iterator, clazz, minfo, context)) {
                 edited = true;
+                int size2 = iterator.getCodeLength();
+                if (size != size2)  // the body was modified.
+                    endPos += size2 - size;
+            }
+        }
 
         return edited;
     }