summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/javassist/bytecode/CodeAnalyzer.java31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/main/javassist/bytecode/CodeAnalyzer.java b/src/main/javassist/bytecode/CodeAnalyzer.java
index e8999065..a078e1f6 100644
--- a/src/main/javassist/bytecode/CodeAnalyzer.java
+++ b/src/main/javassist/bytecode/CodeAnalyzer.java
@@ -74,6 +74,8 @@ class CodeAnalyzer implements Opcode {
int codeLength = stack.length;
ci.move(index);
int stackDepth = -stack[index];
+ int[] jsrDepth = new int[1];
+ jsrDepth[0] = -1;
while (ci.hasNext()) {
index = ci.next();
stack[index] = stackDepth;
@@ -82,7 +84,7 @@ class CodeAnalyzer implements Opcode {
if (stackDepth < 1)
throw new BadBytecode("stack underflow at " + index);
- if (processBranch(op, ci, index, codeLength, stack, stackDepth))
+ if (processBranch(op, ci, index, codeLength, stack, stackDepth, jsrDepth))
break;
if (isEnd(op)) // return, ireturn, athrow, ...
@@ -94,7 +96,7 @@ class CodeAnalyzer implements Opcode {
}
private boolean processBranch(int opcode, CodeIterator ci, int index,
- int codeLength, int[] stack, int stackDepth)
+ int codeLength, int[] stack, int stackDepth, int[] jsrDepth)
throws BadBytecode
{
if ((IFEQ <= opcode && opcode <= IF_ACMPNE)
@@ -121,17 +123,34 @@ class CodeAnalyzer implements Opcode {
target = index + ci.s32bitAt(index + 1);
checkTarget(index, target, codeLength, stack, stackDepth);
- if (stackDepth == 2) // stackDepth is 1 if empty
+ /*
+ * It is unknown which RET comes back to this JSR.
+ * So we assume that if the stack depth at one JSR instruction
+ * is N, then it is also N at other JSRs and N - 1 at all RET
+ * instructions. Note that STACK_GROW[JSR] is 1 since it pushes
+ * a return address on the operand stack.
+ */
+ if (jsrDepth[0] < 0) {
+ jsrDepth[0] = stackDepth;
+ return false;
+ }
+ else if (stackDepth == jsrDepth[0])
return false;
else
throw new BadBytecode(
- "sorry, cannot compute this data flow due to JSR");
+ "sorry, cannot compute this data flow due to JSR: "
+ + stackDepth + "," + jsrDepth[0]);
case RET :
- if (stackDepth == 1) // stackDepth is 1 if empty
+ if (jsrDepth[0] < 0) {
+ jsrDepth[0] = stackDepth + 1;
+ return false;
+ }
+ else if (stackDepth + 1 == jsrDepth[0])
return true;
else
throw new BadBytecode(
- "sorry, cannot compute this data flow due to RET");
+ "sorry, cannot compute this data flow due to RET: "
+ + stackDepth + "," + jsrDepth[0]);
case LOOKUPSWITCH :
case TABLESWITCH :
index2 = (index & ~3) + 4;