]> source.dussan.org Git - javassist.git/commitdiff
fixed JASSIST-175
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sat, 20 Oct 2012 10:57:51 +0000 (10:57 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sat, 20 Oct 2012 10:57:51 +0000 (10:57 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@675 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

Readme.html
javassist.jar
src/main/javassist/bytecode/BadBytecode.java
src/main/javassist/bytecode/stackmap/MapMaker.java
src/test/javassist/bytecode/StackMapTest.java

index 72933367d79048df149aa1e50dff85eb3a79e889..4a5e00a6fe46f6b23307b63bbea57d586c130058 100644 (file)
@@ -284,7 +284,7 @@ see javassist.Dump.
 <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
index dd1d584399dad3bd6a92e0a464213dc551501910..87393d38453b9dc977ec832f6d9e3943b6fc073f 100644 (file)
Binary files a/javassist.jar and b/javassist.jar differ
index 71e5bb9d2a7810ae26c24e3a28129175e8434907..9959ae6c96d0ff945627058e85cafc9d93f3f889 100644 (file)
@@ -31,4 +31,10 @@ public class BadBytecode extends Exception {
     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);
+    }
 }
index b846661bd5888069e6220155bfd532719c06a004..3c96a36abe309f886b72f9c635b339547cc70868 100644 (file)
@@ -96,7 +96,13 @@ public class MapMaker extends Tracer {
             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 @@ public class MapMaker extends Tracer {
             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 @@ public class MapMaker extends Tracer {
     {
         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 @@ public class MapMaker extends Tracer {
      * 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 @@ public class MapMaker extends Tracer {
                 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;
         }
index 876b335e26cfaa2490a9668a99a67bd40dee3c9b..0fdcf2cd6773f62999fbf0844bf9efc41afd2fe9 100644 (file)
@@ -647,6 +647,66 @@ public class StackMapTest extends TestCase {
         }
     }
 
+    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");