aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/CtBehavior.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist/CtBehavior.java')
-rw-r--r--src/main/javassist/CtBehavior.java82
1 files changed, 69 insertions, 13 deletions
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;
}
}