From 607add0f2d4f1413d9d2ba8e19b9e50fa62c888b Mon Sep 17 00:00:00 2001 From: chiba Date: Thu, 15 Jul 2010 16:13:25 +0000 Subject: [PATCH] better support of JSR/RET when computing MaxStack git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@555 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- src/main/javassist/bytecode/CodeAnalyzer.java | 31 +++++++++++++++---- 1 file 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; -- 2.39.5