[jboss-cvs] javassist SVN: r675 - in trunk: src/main/javassist/bytecode and 2 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Sat Oct 20 06:57:52 EDT 2012


Author: chiba
Date: 2012-10-20 06:57:51 -0400 (Sat, 20 Oct 2012)
New Revision: 675

Modified:
   trunk/Readme.html
   trunk/javassist.jar
   trunk/src/main/javassist/bytecode/BadBytecode.java
   trunk/src/main/javassist/bytecode/stackmap/MapMaker.java
   trunk/src/test/javassist/bytecode/StackMapTest.java
Log:
fixed JASSIST-175

Modified: trunk/Readme.html
===================================================================
--- trunk/Readme.html	2012-10-19 07:17:44 UTC (rev 674)
+++ trunk/Readme.html	2012-10-20 10:57:51 UTC (rev 675)
@@ -284,7 +284,7 @@
 <p>-version 3.17
 <ul>
 	<li>OSGi bundle info is now included in the jar file.
-	<li>JIRA JASSIST-160, 163, 166, 168, 170, 171, 174 have been fixed.
+	<li>JIRA JASSIST-160, 163, 166, 168, 170, 171, 174, 175 have been fixed.
 </ul>
 
 <p>-version 3.16.1 on March 6, 2012

Modified: trunk/javassist.jar
===================================================================
(Binary files differ)

Modified: trunk/src/main/javassist/bytecode/BadBytecode.java
===================================================================
--- trunk/src/main/javassist/bytecode/BadBytecode.java	2012-10-19 07:17:44 UTC (rev 674)
+++ trunk/src/main/javassist/bytecode/BadBytecode.java	2012-10-20 10:57:51 UTC (rev 675)
@@ -31,4 +31,10 @@
     public BadBytecode(String msg, Throwable cause) {
         super(msg, cause);
     }
+
+    public BadBytecode(MethodInfo minfo, Throwable cause) {
+        super(minfo.toString() + " in "
+              + minfo.getConstPool().getClassName()
+              + ": " + cause.getMessage(), cause);
+    }
 }

Modified: trunk/src/main/javassist/bytecode/stackmap/MapMaker.java
===================================================================
--- trunk/src/main/javassist/bytecode/stackmap/MapMaker.java	2012-10-19 07:17:44 UTC (rev 674)
+++ trunk/src/main/javassist/bytecode/stackmap/MapMaker.java	2012-10-20 10:57:51 UTC (rev 675)
@@ -96,7 +96,13 @@
             return null;
 
         MapMaker mm = new MapMaker(classes, minfo, ca);
-        mm.make(blocks, ca.getCode());
+        try {
+            mm.make(blocks, ca.getCode());
+        }
+        catch (BadBytecode bb) {
+            throw new BadBytecode(minfo, bb);
+        }
+
         return mm.toStackMap(blocks);
     }
 
@@ -117,7 +123,12 @@
             return null;
 
         MapMaker mm = new MapMaker(classes, minfo, ca);
-        mm.make(blocks, ca.getCode());
+        try {
+            mm.make(blocks, ca.getCode());
+        }
+        catch (BadBytecode bb) {
+            throw new BadBytecode(minfo, bb);
+        }
         return mm.toStackMap2(minfo.getConstPool(), blocks);
     }
 
@@ -137,7 +148,7 @@
     {
         make(code, blocks[0]);
         try {
-            fixTypes(blocks);
+            fixTypes(code, blocks);
         } catch (NotFoundException e) {
             throw new BadBytecode("failed to resolve types", e);
         }
@@ -276,22 +287,40 @@
      * Since SCCs are found in the topologically sorted order,
      * their types are also fixed when they are found. 
      */
-    private void fixTypes(TypedBlock[] blocks) throws NotFoundException {
+    private void fixTypes(byte[] code, TypedBlock[] blocks) throws NotFoundException, BadBytecode {
         ArrayList preOrder = new ArrayList();
         int len = blocks.length;
         int index = 0;
         for (int i = 0; i < len; i++) {
             TypedBlock block = blocks[i];
-            int n = block.localsTypes.length;
-            for (int j = 0; j < n; j++)
-                index = block.localsTypes[j].dfs(preOrder, index, classPool);
+            if (block.localsTypes == null)  // if block is dead code
+                fixDeadcode(code, block);
+            else {
+                int n = block.localsTypes.length;
+                for (int j = 0; j < n; j++)
+                    index = block.localsTypes[j].dfs(preOrder, index, classPool);
 
-            n = block.stackTop;
-            for (int j = 0; j < n; j++)
-                index = block.stackTypes[j].dfs(preOrder, index, classPool); 
+                n = block.stackTop;
+                for (int j = 0; j < n; j++)
+                    index = block.stackTypes[j].dfs(preOrder, index, classPool);
+            }
         }
     }
 
+    private void fixDeadcode(byte[] code, TypedBlock block) throws BadBytecode {
+        int pos = block.position;
+        int len = block.length - 3;
+        if (len < 0)
+            throw new BadBytecode("dead code detected at " + pos
+                                  + ".  No stackmap table generated.");
+
+        for (int k = 0; k < len; k++) 
+            code[pos + k] = Bytecode.NOP;
+
+        code[pos + len] = (byte)Bytecode.GOTO;
+        ByteArray.write16bit(-len, code, pos + len + 1);
+    }
+
     // Phase 3
 
     public StackMapTable toStackMap(TypedBlock[] blocks) {
@@ -314,6 +343,12 @@
                 offsetDelta = bb.length - 1;
                 prev = bb;
             }
+            else if (bb.incoming == 0) {
+                // dead code.
+                writer.sameFrame(offsetDelta);
+                offsetDelta = bb.length - 1;
+                prev = bb;
+            }
             else
                 offsetDelta += bb.length;
         }

Modified: trunk/src/test/javassist/bytecode/StackMapTest.java
===================================================================
--- trunk/src/test/javassist/bytecode/StackMapTest.java	2012-10-19 07:17:44 UTC (rev 674)
+++ trunk/src/test/javassist/bytecode/StackMapTest.java	2012-10-20 10:57:51 UTC (rev 675)
@@ -647,6 +647,66 @@
         }
     }
 
+    public void testJIRA175() throws Exception {
+        CtClass cc = loader.get("javassist.bytecode.StackMapTest$C5");
+        cc.getDeclaredMethod("setter").instrument(new javassist.expr.ExprEditor() {
+            @Override
+            public void edit(javassist.expr.FieldAccess f) throws javassist.CannotCompileException {
+                if (!f.where().getMethodInfo().isMethod())
+                    return;
+
+                f.replace("{ $_ = $proceed($$); if (false) return $_;}");
+            }
+        });
+        cc.writeFile();
+        Object t1 = make(cc.getName());
+        assertEquals(3, invoke(t1, "test"));
+    }
+
+    public static class C5 {
+        String value;
+        int ivalue;
+        public int test() {
+            setter("foo");
+            return value.length();
+        }
+
+        public void setter(String s) {
+            value = s;
+            ivalue = s.length();
+        }
+    }
+
+    public void testJIRA175b() throws Exception {
+        CtClass cc = loader.get("javassist.bytecode.StackMapTest$C6");
+        try {
+            cc.getDeclaredMethod("setter").instrument(new javassist.expr.ExprEditor() {
+                public void edit(javassist.expr.FieldAccess f) throws javassist.CannotCompileException {
+                    if (!f.where().getMethodInfo().isMethod())
+                        return;
+
+                    f.replace("{ $_ = $proceed($$); return $_;}");
+                }
+            });
+            fail("deadcode detection");
+        }
+        catch (javassist.CannotCompileException e) {}
+    }
+
+    public static class C6 {
+        String value;
+        int ivalue;
+        public int test() {
+            setter("foo");
+            return value.length();
+        }
+
+        public void setter(String s) {
+            value = s;
+            ivalue = s.length();
+        }
+    }
+
     public void tstCtClassType() throws Exception {
         ClassPool cp = ClassPool.getDefault();
         CtClass cc = cp.get("javassist.CtClassType");



More information about the jboss-cvs-commits mailing list