diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2012-11-25 18:40:56 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2012-11-25 18:40:56 +0000 |
commit | e3e129bbcc06ad0be9ee067ed29c349ba88a6ce1 (patch) | |
tree | 7a2d8ae10239a36d589de5cf0a2291791f9643a1 | |
parent | b1e4ecb1fd042961fe649de5e27ca70c416e9d3a (diff) | |
download | javassist-e3e129bbcc06ad0be9ee067ed29c349ba88a6ce1.tar.gz javassist-e3e129bbcc06ad0be9ee067ed29c349ba88a6ce1.zip |
fixed JASSIST-177
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@691 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
-rw-r--r-- | javassist.jar | bin | 675068 -> 701499 bytes | |||
-rw-r--r-- | src/main/javassist/CtBehavior.java | 48 | ||||
-rw-r--r-- | src/test/javassist/JvstTest4.java | 33 | ||||
-rw-r--r-- | src/test/test4/AfterTest.java | 119 |
4 files changed, 182 insertions, 18 deletions
diff --git a/javassist.jar b/javassist.jar Binary files differindex 42b02760..b8f4ca34 100644 --- a/javassist.jar +++ b/javassist.jar diff --git a/src/main/javassist/CtBehavior.java b/src/main/javassist/CtBehavior.java index 1ca8408b..73ac277a 100644 --- a/src/main/javassist/CtBehavior.java +++ b/src/main/javassist/CtBehavior.java @@ -826,35 +826,44 @@ public abstract class CtBehavior extends CtMember { // finally clause for exceptions int handlerLen = insertAfterHandler(asFinally, b, rtype, varNo, jv, src); - // finally clause for normal termination - insertAfterAdvice(b, jv, src, pool, rtype, varNo); - - ca.setMaxStack(b.getMaxStack()); - ca.setMaxLocals(b.getMaxLocals()); - - int gapPos = iterator.append(b.get()); - iterator.append(b.getExceptionTable(), gapPos); - + int handlerPos = iterator.getCodeLength(); if (asFinally) - ca.getExceptionTable().add(getStartPosOfBody(ca), gapPos, gapPos, 0); - - int gapLen = iterator.getCodeLength() - gapPos - handlerLen; - int subr = iterator.getCodeLength() - gapLen; + ca.getExceptionTable().add(getStartPosOfBody(ca), handlerPos, handlerPos, 0); + int adviceLen = 0; + int advicePos = 0; + boolean noReturn = true; while (iterator.hasNext()) { int pos = iterator.next(); - if (pos >= subr) + if (pos >= handlerPos) break; int c = iterator.byteAt(pos); if (c == Opcode.ARETURN || c == Opcode.IRETURN || c == Opcode.FRETURN || c == Opcode.LRETURN || c == Opcode.DRETURN || c == Opcode.RETURN) { - insertGoto(iterator, subr, pos); - subr = iterator.getCodeLength() - gapLen; + 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; + handlerPos = advicePos - handlerLen; } } + if (noReturn) { + handlerPos = iterator.append(b.get()); + iterator.append(b.getExceptionTable(), handlerPos); + } + + ca.setMaxStack(b.getMaxStack()); + ca.setMaxLocals(b.getMaxLocals()); methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); } catch (NotFoundException e) { @@ -868,10 +877,11 @@ public abstract class CtBehavior extends CtMember { } } - private void insertAfterAdvice(Bytecode code, Javac jv, String src, - ConstPool cp, CtClass rtype, int varNo) + private int insertAfterAdvice(Bytecode code, Javac jv, String src, + ConstPool cp, CtClass rtype, int varNo) throws CompileError { + int pc = code.currentPc(); if (rtype == CtClass.voidType) { code.addOpcode(Opcode.ACONST_NULL); code.addAstore(varNo); @@ -889,6 +899,8 @@ public abstract class CtBehavior extends CtMember { else code.addOpcode(Opcode.ARETURN); } + + return code.currentPc() - pc; } /* diff --git a/src/test/javassist/JvstTest4.java b/src/test/javassist/JvstTest4.java index 76f139bd..7cf6178a 100644 --- a/src/test/javassist/JvstTest4.java +++ b/src/test/javassist/JvstTest4.java @@ -784,4 +784,37 @@ public class JvstTest4 extends JvstTestRoot { + "org.apache.hadoop.mapreduce.Mapper<java.lang.Object, org.apache.hadoop.io.Text, " + "org.apache.hadoop.io.Text, org.apache.hadoop.io.IntWritable>.Context) void", s); } + + public void testAfter() throws Exception { + CtClass cc = sloader.get("test4.AfterTest"); + CtMethod m1 = cc.getDeclaredMethod("m1"); + m1.insertAfter("print();"); + CtMethod m2 = cc.getDeclaredMethod("m2"); + m2.insertAfter("print();"); + CtMethod m3 = cc.getDeclaredMethod("m3"); + m3.insertAfter("print();"); + CtMethod m4 = cc.getDeclaredMethod("m4"); + m4.insertAfter("print();"); + + CtMethod mm1 = cc.getDeclaredMethod("mm1"); + mm1.insertAfter("print();", true); + CtMethod mm2 = cc.getDeclaredMethod("mm2"); + mm2.insertAfter("print();", true); + CtMethod mm3 = cc.getDeclaredMethod("mm3"); + mm3.insertAfter("print();", true); + CtMethod mm4 = cc.getDeclaredMethod("mm4"); + mm4.insertAfter("print();", true); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(131, invoke(obj, "test1")); + assertEquals(112, invoke(obj, "test2")); + assertEquals(10, invoke(obj, "test3")); + assertEquals(100, invoke(obj, "test4")); + + assertEquals(131, invoke(obj, "test11")); + assertEquals(112, invoke(obj, "test22")); + assertEquals(10, invoke(obj, "test33")); + assertEquals(100, invoke(obj, "test44")); + } } diff --git a/src/test/test4/AfterTest.java b/src/test/test4/AfterTest.java new file mode 100644 index 00000000..3ba36504 --- /dev/null +++ b/src/test/test4/AfterTest.java @@ -0,0 +1,119 @@ +package test4; + +public class AfterTest { + public void print() { System.out.println("test4.AfterTest"); } + + public int test1() { return m1(10) + m1(-10); } + + public int m1(int i) { + if (i > 0) + i = i + 10; + else + return -i; + + i = i + 100; + return i + 1; + } + + public int test2() throws Exception { return m2(1); } + + public int m2(int i) throws Exception { + if (i > 10) + throw new Exception(); + else if (i > 0) + i = i + 10; + else + return -i; + + i = i + 100; + return i + 1; + } + + public int test3() throws Exception { return m3(-10); } + + public int m3(int i) throws Exception { + if (i > 10) + throw new Exception(); + else if (i > 0) + i = i + 10; + else + return -i; + + i = i + 100; + throw new Exception(); + } + + public int test4() throws Exception { + try { + return m4(-10); + } + catch (Exception e) { + return 100; + } + } + + public int m4(int i) throws Exception { + if (i > 0) + i = i + 10; + + i = i + 100; + throw new Exception(); + } + + public int test11() { return mm1(10) + mm1(-10); } + + public int mm1(int i) { + if (i > 0) + i = i + 10; + else + return -i; + + i = i + 100; + return i + 1; + } + + public int test22() throws Exception { return mm2(1); } + + public int mm2(int i) throws Exception { + if (i > 10) + throw new Exception(); + else if (i > 0) + i = i + 10; + else + return -i; + + i = i + 100; + return i + 1; + } + + public int test33() throws Exception { return mm3(-10); } + + public int mm3(int i) throws Exception { + if (i > 10) + throw new Exception(); + else if (i > 0) + i = i + 10; + else + return -i; + + i = i + 100; + throw new Exception(); + } + + public int test44() throws Exception { + try { + return mm4(-10); + } + catch (Exception e) { + return 100; + } + } + + public int mm4(int i) throws Exception { + if (i > 0) + i = i + 10; + + i = i + 100; + throw new Exception(); + } +} |