aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchibash <chiba@javassist.org>2019-09-20 23:20:39 +0900
committerchibash <chiba@javassist.org>2019-09-20 23:20:39 +0900
commit91086509023cb7cfac0132553ee2871859ad6721 (patch)
treec3ca739488cd20a2668caf0b9d330324fa4ed340
parentf7ef31ce8b723e425a66aafb8c0beddeabfe9a66 (diff)
downloadjavassist-91086509023cb7cfac0132553ee2871859ad6721.tar.gz
javassist-91086509023cb7cfac0132553ee2871859ad6721.zip
adds CtBehavior#insertAfter(String,boolean,boolean) for Issue #275
-rw-r--r--Readme.html2
-rw-r--r--build.xml4
-rw-r--r--javassist.jarbin774695 -> 771168 bytes
-rw-r--r--pom.xml4
-rw-r--r--src/main/javassist/CtBehavior.java82
-rw-r--r--src/main/javassist/bytecode/CodeIterator.java44
-rw-r--r--src/test/javassist/JvstTest5.java12
-rw-r--r--src/test/test5/InsertAfter.java35
8 files changed, 159 insertions, 24 deletions
diff --git a/Readme.html b/Readme.html
index 461c614a..0ce25f57 100644
--- a/Readme.html
+++ b/Readme.html
@@ -283,7 +283,7 @@ see javassist.Dump.
<p>-version 3.26
<ul>
- <li>GitHub Issue #270 (PR #272), Issue #265 (PR #267), Issue #271 and #222.
+ <li>GitHub Issue #270 (PR #272), #265 (PR #267), #271, #222, and #275.
</ul>
<p>-version 3.25 on April 16, 2019
diff --git a/build.xml b/build.xml
index da6101fc..f8246c7a 100644
--- a/build.xml
+++ b/build.xml
@@ -79,8 +79,8 @@
destdir="${build.classes.dir}"
debug="on"
deprecation="on"
- source="1.7"
- target="1.7"
+ source="1.8"
+ target="1.8"
optimize="off"
includeantruntime="true"
includes="**">
diff --git a/javassist.jar b/javassist.jar
index 19969da0..6ca56990 100644
--- a/javassist.jar
+++ b/javassist.jar
Binary files differ
diff --git a/pom.xml b/pom.xml
index cbc25375..89584133 100644
--- a/pom.xml
+++ b/pom.xml
@@ -151,8 +151,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
- <source>1.7</source>
- <target>1.7</target>
+ <source>1.8</source>
+ <target>1.8</target>
<testSource>11</testSource>
<testTarget>11</testTarget>
<testCompilerArgument>-parameters</testCompilerArgument>
diff --git a/src/main/javassist/CtBehavior.java b/src/main/javassist/CtBehavior.java
index a0738ec7..fd3dac96 100644
--- a/src/main/javassist/CtBehavior.java
+++ b/src/main/javassist/CtBehavior.java
@@ -812,7 +812,7 @@ public abstract class CtBehavior extends CtMember {
/**
* Inserts bytecode at the end of the body.
- * The bytecode is inserted just before every return insturction.
+ * The bytecode is inserted just before every return instruction.
* It is not executed when an exception is thrown.
*
* @param src the source code representing the inserted bytecode.
@@ -821,12 +821,12 @@ public abstract class CtBehavior extends CtMember {
public void insertAfter(String src)
throws CannotCompileException
{
- insertAfter(src, false);
+ insertAfter(src, false, false);
}
/**
* Inserts bytecode at the end of the body.
- * The bytecode is inserted just before every return insturction.
+ * The bytecode is inserted just before every return instruction.
*
* @param src the source code representing the inserted bytecode.
* It must be a single statement or block.
@@ -839,6 +839,30 @@ public abstract class CtBehavior extends CtMember {
public void insertAfter(String src, boolean asFinally)
throws CannotCompileException
{
+ insertAfter(src, asFinally, false);
+ }
+
+ /**
+ * Inserts bytecode at the end of the body.
+ * The bytecode is inserted just before every return instruction.
+ *
+ * @param src the source code representing the inserted bytecode.
+ * It must be a single statement or block.
+ * @param asFinally true if the inserted bytecode is executed
+ * not only when the control normally returns
+ * but also when an exception is thrown.
+ * If this parameter is true, the inserted code cannot
+ * access local variables.
+ * @param redundant if true, redundant bytecode will be generated.
+ * the redundancy is necessary when some compilers (Kotlin?)
+ * generate the original bytecode.
+ * The other <code>insertAfter</code> methods calls this method
+ * with <code>false</code> for this parameter.
+ * @since 3.26
+ */
+ public void insertAfter(String src, boolean asFinally, boolean redundant)
+ throws CannotCompileException
+ {
CtClass cc = declaringClass;
cc.checkModify();
ConstPool pool = methodInfo.getConstPool();
@@ -878,18 +902,50 @@ public abstract class CtBehavior extends CtMember {
if (c == Opcode.ARETURN || c == Opcode.IRETURN
|| c == Opcode.FRETURN || c == Opcode.LRETURN
|| c == Opcode.DRETURN || c == Opcode.RETURN) {
- if (noReturn) {
- // finally clause for normal termination
- adviceLen = insertAfterAdvice(b, jv, src, pool, rtype, varNo);
- handlerPos = iterator.append(b.get());
- iterator.append(b.getExceptionTable(), handlerPos);
+ if (redundant) {
+ iterator.setMark2(handlerPos);
+ Bytecode bcode;
+ Javac jvc;
+ int retVarNo;
+ if (noReturn) {
+ noReturn = false;
+ bcode = b;
+ jvc = jv;
+ retVarNo = varNo;
+ }
+ else {
+ bcode = new Bytecode(pool, 0, retAddr + 1);
+ bcode.setStackDepth(ca.getMaxStack() + 1);
+ jvc = new Javac(bcode, cc);
+ int nvars2 = jvc.recordParams(getParameterTypes(),
+ Modifier.isStatic(getModifiers()));
+ jvc.recordParamNames(ca, nvars2);
+ retVarNo = jvc.recordReturnType(rtype, true);
+ jvc.recordLocalVariables(ca, 0);
+ }
+
+ int adviceLen2 = insertAfterAdvice(bcode, jvc, src, pool, rtype, retVarNo);
+ int offset = iterator.append(bcode.get());
+ iterator.append(bcode.getExceptionTable(), offset);
+ int advicePos2 = iterator.getCodeLength() - adviceLen2;
+ insertGoto(iterator, advicePos2, pos);
+ handlerPos = iterator.getMark2();
+ }
+ else {
+ if (noReturn) {
+ // finally clause for normal termination
+ adviceLen = insertAfterAdvice(b, jv, src, pool, rtype, varNo);
+ handlerPos = iterator.append(b.get());
+ iterator.append(b.getExceptionTable(), handlerPos);
+ advicePos = iterator.getCodeLength() - adviceLen;
+ handlerLen = advicePos - handlerPos;
+ noReturn = false;
+ }
+
+ insertGoto(iterator, advicePos, pos);
advicePos = iterator.getCodeLength() - adviceLen;
- handlerLen = advicePos - handlerPos;
- noReturn = false;
+ handlerPos = advicePos - handlerLen;
}
- insertGoto(iterator, advicePos, pos);
- advicePos = iterator.getCodeLength() - adviceLen;
- handlerPos = advicePos - handlerLen;
}
}
diff --git a/src/main/javassist/bytecode/CodeIterator.java b/src/main/javassist/bytecode/CodeIterator.java
index b9a23c2c..6281ec2d 100644
--- a/src/main/javassist/bytecode/CodeIterator.java
+++ b/src/main/javassist/bytecode/CodeIterator.java
@@ -52,7 +52,7 @@ public class CodeIterator implements Opcode {
protected byte[] bytecode;
protected int endPos;
protected int currentPos;
- protected int mark;
+ protected int mark, mark2;
protected CodeIterator(CodeAttribute ca) {
codeAttr = ca;
@@ -64,7 +64,7 @@ public class CodeIterator implements Opcode {
* Moves to the first instruction.
*/
public void begin() {
- currentPos = mark = 0;
+ currentPos = mark = mark2 = 0;
endPos = getCodeLength();
}
@@ -99,6 +99,20 @@ public class CodeIterator implements Opcode {
}
/**
+ * Sets a mark to the bytecode at the given index.
+ * The mark can be used to track the position of that bytecode
+ * when code blocks are inserted.
+ * If a code block is inclusively inserted at the position of the
+ * bytecode, the mark is set to the inserted code block.
+ *
+ * @see #getMark2()
+ * @since 3.26
+ */
+ public void setMark2(int index) {
+ mark2 = index;
+ }
+
+ /**
* Gets the index of the position of the mark set by
* <code>setMark</code>.
*
@@ -109,6 +123,16 @@ public class CodeIterator implements Opcode {
public int getMark() { return mark; }
/**
+ * Gets the index of the position of the mark set by
+ * <code>setMark2</code>.
+ *
+ * @return the index of the position.
+ * @see #setMark2(int)
+ * @since 3.26
+ */
+ public int getMark2() { return mark2; }
+
+ /**
* Returns a Code attribute read with this iterator.
*/
public CodeAttribute get() {
@@ -646,6 +670,9 @@ public class CodeIterator implements Opcode {
if (mark > pos || (mark == pos && exclusive))
mark += length2;
+
+ if (mark2 > pos || (mark2 == pos && exclusive))
+ mark2 += length2;
}
codeAttr.setCode(c);
@@ -1012,16 +1039,17 @@ public class CodeIterator implements Opcode {
static class Pointers {
int cursor;
- int mark0, mark;
+ int mark0, mark, mark2;
ExceptionTable etable;
LineNumberAttribute line;
LocalVariableAttribute vars, types;
StackMapTable stack;
StackMap stack2;
- Pointers(int cur, int m, int m0, ExceptionTable et, CodeAttribute ca) {
+ Pointers(int cur, int m, int m2, int m0, ExceptionTable et, CodeAttribute ca) {
cursor = cur;
mark = m;
+ mark2 = m2;
mark0 = m0;
etable = et; // non null
line = (LineNumberAttribute)ca.getAttribute(LineNumberAttribute.tag);
@@ -1038,6 +1066,9 @@ public class CodeIterator implements Opcode {
if (where < mark || (where == mark && exclusive))
mark += gapLength;
+ if (where < mark2 || (where == mark2 && exclusive))
+ mark2 += gapLength;
+
if (where < mark0 || (where == mark0 && exclusive))
mark0 += gapLength;
@@ -1074,7 +1105,7 @@ public class CodeIterator implements Opcode {
CodeAttribute ca, CodeAttribute.LdcEntry ldcs)
throws BadBytecode
{
- Pointers pointers = new Pointers(0, 0, 0, etable, ca);
+ Pointers pointers = new Pointers(0, 0, 0, 0, etable, ca);
List<Branch> jumps = makeJumpList(code, code.length, pointers);
while (ldcs != null) {
addLdcW(ldcs, jumps);
@@ -1118,11 +1149,12 @@ public class CodeIterator implements Opcode {
if (gapLength <= 0)
return code;
- Pointers pointers = new Pointers(currentPos, mark, where, etable, ca);
+ Pointers pointers = new Pointers(currentPos, mark, mark2, where, etable, ca);
List<Branch> jumps = makeJumpList(code, code.length, pointers);
byte[] r = insertGap2w(code, where, gapLength, exclusive, jumps, pointers);
currentPos = pointers.cursor;
mark = pointers.mark;
+ mark2 = pointers.mark2;
int where2 = pointers.mark0;
if (where2 == currentPos && !exclusive)
currentPos += gapLength;
diff --git a/src/test/javassist/JvstTest5.java b/src/test/javassist/JvstTest5.java
index 4d4fc719..c2ee9992 100644
--- a/src/test/javassist/JvstTest5.java
+++ b/src/test/javassist/JvstTest5.java
@@ -546,4 +546,16 @@ public class JvstTest5 extends JvstTestRoot {
Object obj = make(cc.getName());
assertEquals(1, invoke(obj, "run"));
}
+
+ // Issue #275
+ public void testRedundantInsertAfter() throws Exception {
+ CtClass cc = sloader.get(test5.InsertAfter.class.getName());
+ CtMethod m = cc.getDeclaredMethod("foo");
+ m.insertAfter("{ $_ += 1; }", false, true);
+ CtMethod m2 = cc.getDeclaredMethod("bar");
+ m2.insertAfter("{ $_ += 1; }", true, true);
+ cc.writeFile();
+ Object obj = make(cc.getName());
+ assertEquals(1, invoke(obj, "run"));
+ }
}
diff --git a/src/test/test5/InsertAfter.java b/src/test/test5/InsertAfter.java
new file mode 100644
index 00000000..6d62c06a
--- /dev/null
+++ b/src/test/test5/InsertAfter.java
@@ -0,0 +1,35 @@
+package test5;
+
+public class InsertAfter {
+ public int run() {
+ return foo(7) + bar(20);
+ }
+
+ public int foo(int k) {
+ if (k > 0)
+ if (k > 10)
+ return k + 1;
+ else
+ return k * 10;
+ else
+ return k * 100;
+ }
+
+ public int bar(int k) {
+ if (k > 0)
+ try {
+ if (k > 10)
+ return k + 1;
+ else
+ return k * 10;
+ }
+ catch (Exception e) {
+ if (k > 0)
+ return k * 1000;
+ else
+ throw e;
+ }
+ else
+ return k * 100;
+ }
+}