diff options
Diffstat (limited to 'src/main/javassist/CtBehavior.java')
-rw-r--r-- | src/main/javassist/CtBehavior.java | 82 |
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; } } |