[jboss-cvs] javassist SVN: r555 - trunk/src/main/javassist/bytecode.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Jul 15 12:13:26 EDT 2010


Author: chiba
Date: 2010-07-15 12:13:25 -0400 (Thu, 15 Jul 2010)
New Revision: 555

Modified:
   trunk/src/main/javassist/bytecode/CodeAnalyzer.java
Log:
better support of JSR/RET when computing MaxStack 

Modified: trunk/src/main/javassist/bytecode/CodeAnalyzer.java
===================================================================
--- trunk/src/main/javassist/bytecode/CodeAnalyzer.java	2010-07-09 10:20:46 UTC (rev 554)
+++ trunk/src/main/javassist/bytecode/CodeAnalyzer.java	2010-07-15 16:13:25 UTC (rev 555)
@@ -74,6 +74,8 @@
         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 @@
             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 @@
     }
 
     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 @@
                     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;



More information about the jboss-cvs-commits mailing list