// 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) {
}
}
- 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);
else
code.addOpcode(Opcode.ARETURN);
}
+
+ return code.currentPc() - pc;
}
/*
+ "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"));
+ }
}
--- /dev/null
+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();
+ }
+}