]> source.dussan.org Git - javassist.git/commitdiff
fixed JIRA JASSIST-125
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sun, 18 Jul 2010 01:18:54 +0000 (01:18 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sun, 18 Jul 2010 01:18:54 +0000 (01:18 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@556 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

src/main/javassist/bytecode/stackmap/BasicBlock.java
src/main/javassist/bytecode/stackmap/Tracer.java

index e085dbb20c043bde40c1e2a5366f261679982425..e5b64d34be79f8e00ffc65f7d05feba15a9e4622 100644 (file)
@@ -19,6 +19,12 @@ import javassist.bytecode.*;
 import java.util.HashMap;
 import java.util.ArrayList;
 
+/**
+ * A basic block is a sequence of bytecode that does not contain jump/branch
+ * instructions except at the last bytecode.
+ * Since Java6 or later does not allow JSR, this class deals with JSR as a
+ * non-branch instruction.
+ */
 public class BasicBlock {
     public int position, length;
     public int incoming;        // the number of incoming branches.
@@ -221,12 +227,13 @@ public class BasicBlock {
                 else if (Opcode.GOTO <= op && op <= Opcode.LOOKUPSWITCH)
                     switch (op) {
                     case Opcode.GOTO :
+                        makeGoto(marks, index, index + ci.s16bitAt(index + 1), 3);
+                        break;
                     case Opcode.JSR :
-                        makeGotoJsr(marks, index, index + ci.s16bitAt(index + 1),
-                                    op == Opcode.GOTO, 3);
+                        makeJsr(marks, index, index + ci.s16bitAt(index + 1), 3);
                         break;
                     case Opcode.RET :
-                        makeMark(marks, index, null, 1, true);
+                        makeMark(marks, index, null, 2, true);
                         break;
                     case Opcode.TABLESWITCH : {
                         int pos = (index & ~3) + 4;
@@ -261,9 +268,10 @@ public class BasicBlock {
                     }
                 else if ((Opcode.IRETURN <= op && op <= Opcode.RETURN) || op == Opcode.ATHROW)
                     makeMark(marks, index, null, 1, true);
-                else if (op == Opcode.GOTO_W || op == Opcode.JSR_W)
-                    makeGotoJsr(marks, index, index + ci.s32bitAt(index + 1),
-                                op == Opcode.GOTO_W, 5);
+                else if (op == Opcode.GOTO_W)
+                    makeGoto(marks, index, index + ci.s32bitAt(index + 1), 5);
+                else if (op == Opcode.JSR_W)
+                    makeJsr(marks, index, index + ci.s32bitAt(index + 1), 5);
                 else if (op == Opcode.WIDE && ci.byteAt(index + 1) == Opcode.RET)
                     makeMark(marks, index, null, 1, true);
             }
@@ -279,17 +287,22 @@ public class BasicBlock {
             return marks;
         }
 
-        private void makeGotoJsr(HashMap marks, int pos, int target, boolean isGoto, int size) {
+        private void makeGoto(HashMap marks, int pos, int target, int size) {
             Mark to = makeMark(marks, target);
-            BasicBlock[] jumps;
-            if (isGoto)
-                jumps = makeArray(to.block);
-            else {
-                Mark next = makeMark(marks, pos + size);
-                jumps = makeArray(to.block, next.block);
-            }
+            BasicBlock[] jumps = makeArray(to.block);
+            makeMark(marks, pos, jumps, size, true);
+        }
 
-            makeMark(marks, pos, jumps, size, isGoto);
+        /**
+         * We ignore JSR since Java 6 or later does not allow it.
+         */
+        protected void makeJsr(HashMap marks, int pos, int target, int size) {
+        /*
+            Mark to = makeMark(marks, target);
+            Mark next = makeMark(marks, pos + size);
+            BasicBlock[] jumps = makeArray(to.block, next.block);
+            makeMark(marks, pos, jumps, size, false);
+        */
         }
 
         private BasicBlock[] makeBlocks(HashMap markTable) {
index 77f56b64982078bae29b3cbf11ae8005a3431060..837257bc5667950db8be1e78dcf2b586a300c680 100644 (file)
@@ -128,21 +128,22 @@ public abstract class Tracer implements TypeTag {
 
     /**
      * Invoked when the visited instruction is jsr.
+     * Java6 or later does not allow using RET.
      */
     protected void visitJSR(int pos, byte[] code) throws BadBytecode {
-        throwBadBytecode(pos, "jsr");
+        /* Since JSR pushes a return address onto the operand stack,
+         * the stack map at the entry point of a subroutine is
+         * stackTypes resulting after executing the following code:
+         *
+         *     stackTypes[stackTop++] = TOP;
+         */
     }
 
     /**
      * Invoked when the visited instruction is ret or wide ret.
+     * Java6 or later does not allow using RET.
      */
-    protected void visitRET(int pos, byte[] code) throws BadBytecode {
-        throwBadBytecode(pos, "ret");
-    }
-
-    private void throwBadBytecode(int pos, String name) throws BadBytecode {
-        throw new BadBytecode(name + " at " + pos);
-    }
+    protected void visitRET(int pos, byte[] code) throws BadBytecode {}
 
     private int doOpcode0_53(int pos, byte[] code, int op) throws BadBytecode {
         int reg;
@@ -559,12 +560,11 @@ public abstract class Tracer implements TypeTag {
             visitGoto(pos, code, ByteArray.readS16bit(code, pos + 1));
             return 3;       // branch
         case Opcode.JSR :
-            stackTypes[stackTop++] = TOP;       // not allowed?
             visitJSR(pos, code);
             return 3;       // branch
         case Opcode.RET :
             visitRET(pos, code);
-            return 2;                           // not allowed?
+            return 2;
         case Opcode.TABLESWITCH : {
             stackTop--;     // branch
             int pos2 = (pos & ~3) + 8;
@@ -672,7 +672,6 @@ public abstract class Tracer implements TypeTag {
             visitGoto(pos, code, ByteArray.read32bit(code, pos + 1));
             return 5;           // branch
         case Opcode.JSR_W :
-            stackTypes[stackTop++] = TOP;       // not allowed?
             visitJSR(pos, code);
             return 5;
         }