<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.
/**
* 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>.
protected int endPos;
protected int currentPos;
- CodeIterator(CodeAttribute ca) {
+ protected CodeIterator(CodeAttribute ca) {
codeAttr = ca;
bytecode = ca.getCode();
begin();
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
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;
* 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;
}