summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2010-07-15 16:13:25 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2010-07-15 16:13:25 +0000
commit607add0f2d4f1413d9d2ba8e19b9e50fa62c888b (patch)
treec0c6470aad14010c23f249fee6c43fbded1b27d1 /src/main
parent712eedc7e9c102feef07e2bc9082211b770968f8 (diff)
downloadjavassist-607add0f2d4f1413d9d2ba8e19b9e50fa62c888b.tar.gz
javassist-607add0f2d4f1413d9d2ba8e19b9e50fa62c888b.zip
better support of JSR/RET when computing MaxStack
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@555 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
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;