From 799efde9ea61ee071597f101c54469bfcf974ae3 Mon Sep 17 00:00:00 2001 From: chiba Date: Sun, 18 Jul 2010 01:18:54 +0000 Subject: [PATCH] fixed JIRA JASSIST-125 git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@556 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- .../bytecode/stackmap/BasicBlock.java | 43 ++++++++++++------- .../javassist/bytecode/stackmap/Tracer.java | 21 +++++---- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/main/javassist/bytecode/stackmap/BasicBlock.java b/src/main/javassist/bytecode/stackmap/BasicBlock.java index e085dbb2..e5b64d34 100644 --- a/src/main/javassist/bytecode/stackmap/BasicBlock.java +++ b/src/main/javassist/bytecode/stackmap/BasicBlock.java @@ -19,6 +19,12 @@ import javassist.bytecode.*; import java.util.HashMap; import java.util.ArrayList; +/** + * A basic block is a sequence of bytecode that does not contain jump/branch + * instructions except at the last bytecode. + * Since Java6 or later does not allow JSR, this class deals with JSR as a + * non-branch instruction. + */ public class BasicBlock { public int position, length; public int incoming; // the number of incoming branches. @@ -221,12 +227,13 @@ public class BasicBlock { else if (Opcode.GOTO <= op && op <= Opcode.LOOKUPSWITCH) switch (op) { case Opcode.GOTO : + makeGoto(marks, index, index + ci.s16bitAt(index + 1), 3); + break; case Opcode.JSR : - makeGotoJsr(marks, index, index + ci.s16bitAt(index + 1), - op == Opcode.GOTO, 3); + makeJsr(marks, index, index + ci.s16bitAt(index + 1), 3); break; case Opcode.RET : - makeMark(marks, index, null, 1, true); + makeMark(marks, index, null, 2, true); break; case Opcode.TABLESWITCH : { int pos = (index & ~3) + 4; @@ -261,9 +268,10 @@ public class BasicBlock { } else if ((Opcode.IRETURN <= op && op <= Opcode.RETURN) || op == Opcode.ATHROW) makeMark(marks, index, null, 1, true); - else if (op == Opcode.GOTO_W || op == Opcode.JSR_W) - makeGotoJsr(marks, index, index + ci.s32bitAt(index + 1), - op == Opcode.GOTO_W, 5); + else if (op == Opcode.GOTO_W) + makeGoto(marks, index, index + ci.s32bitAt(index + 1), 5); + else if (op == Opcode.JSR_W) + makeJsr(marks, index, index + ci.s32bitAt(index + 1), 5); else if (op == Opcode.WIDE && ci.byteAt(index + 1) == Opcode.RET) makeMark(marks, index, null, 1, true); } @@ -279,17 +287,22 @@ public class BasicBlock { return marks; } - private void makeGotoJsr(HashMap marks, int pos, int target, boolean isGoto, int size) { + private void makeGoto(HashMap marks, int pos, int target, int size) { Mark to = makeMark(marks, target); - BasicBlock[] jumps; - if (isGoto) - jumps = makeArray(to.block); - else { - Mark next = makeMark(marks, pos + size); - jumps = makeArray(to.block, next.block); - } + BasicBlock[] jumps = makeArray(to.block); + makeMark(marks, pos, jumps, size, true); + } - makeMark(marks, pos, jumps, size, isGoto); + /** + * We ignore JSR since Java 6 or later does not allow it. + */ + protected void makeJsr(HashMap marks, int pos, int target, int size) { + /* + Mark to = makeMark(marks, target); + Mark next = makeMark(marks, pos + size); + BasicBlock[] jumps = makeArray(to.block, next.block); + makeMark(marks, pos, jumps, size, false); + */ } private BasicBlock[] makeBlocks(HashMap markTable) { diff --git a/src/main/javassist/bytecode/stackmap/Tracer.java b/src/main/javassist/bytecode/stackmap/Tracer.java index 77f56b64..837257bc 100644 --- a/src/main/javassist/bytecode/stackmap/Tracer.java +++ b/src/main/javassist/bytecode/stackmap/Tracer.java @@ -128,21 +128,22 @@ public abstract class Tracer implements TypeTag { /** * Invoked when the visited instruction is jsr. + * Java6 or later does not allow using RET. */ protected void visitJSR(int pos, byte[] code) throws BadBytecode { - throwBadBytecode(pos, "jsr"); + /* Since JSR pushes a return address onto the operand stack, + * the stack map at the entry point of a subroutine is + * stackTypes resulting after executing the following code: + * + * stackTypes[stackTop++] = TOP; + */ } /** * Invoked when the visited instruction is ret or wide ret. + * Java6 or later does not allow using RET. */ - protected void visitRET(int pos, byte[] code) throws BadBytecode { - throwBadBytecode(pos, "ret"); - } - - private void throwBadBytecode(int pos, String name) throws BadBytecode { - throw new BadBytecode(name + " at " + pos); - } + protected void visitRET(int pos, byte[] code) throws BadBytecode {} private int doOpcode0_53(int pos, byte[] code, int op) throws BadBytecode { int reg; @@ -559,12 +560,11 @@ public abstract class Tracer implements TypeTag { visitGoto(pos, code, ByteArray.readS16bit(code, pos + 1)); return 3; // branch case Opcode.JSR : - stackTypes[stackTop++] = TOP; // not allowed? visitJSR(pos, code); return 3; // branch case Opcode.RET : visitRET(pos, code); - return 2; // not allowed? + return 2; case Opcode.TABLESWITCH : { stackTop--; // branch int pos2 = (pos & ~3) + 8; @@ -672,7 +672,6 @@ public abstract class Tracer implements TypeTag { visitGoto(pos, code, ByteArray.read32bit(code, pos + 1)); return 5; // branch case Opcode.JSR_W : - stackTypes[stackTop++] = TOP; // not allowed? visitJSR(pos, code); return 5; } -- 2.39.5