src/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java

Print this page




  49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  51  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  52  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  53  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  54  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  55  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  56  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  57  * THE POSSIBILITY OF SUCH DAMAGE.
  58  */
  59 
  60 package jdk.internal.org.objectweb.asm.commons;
  61 
  62 import java.util.Collections;
  63 import java.util.Comparator;
  64 
  65 import jdk.internal.org.objectweb.asm.MethodVisitor;
  66 import jdk.internal.org.objectweb.asm.Opcodes;
  67 import jdk.internal.org.objectweb.asm.tree.MethodNode;
  68 import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode;

  69 
  70 /**
  71  * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers
  72  * are sorted in a method innermost-to-outermost. This allows the programmer to
  73  * add handlers without worrying about ordering them correctly with respect to
  74  * existing, in-code handlers.
  75  *
  76  * Behavior is only defined for properly-nested handlers. If any "try" blocks
  77  * overlap (something that isn't possible in Java code) then this may not do
  78  * what you want. In fact, this adapter just sorts by the length of the "try"
  79  * block, taking advantage of the fact that a given try block must be larger
  80  * than any block it contains).
  81  *
  82  * @author Adrian Sampson
  83  */
  84 public class TryCatchBlockSorter extends MethodNode {
  85 
  86     public TryCatchBlockSorter(
  87         final MethodVisitor mv,
  88         final int access,
  89         final String name,
  90         final String desc,
  91         final String signature,
  92         final String[] exceptions)
  93     {
  94         this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions);
  95     }
  96 
  97     protected TryCatchBlockSorter(
  98         final int api,
  99         final MethodVisitor mv,
 100         final int access,
 101         final String name,
 102         final String desc,
 103         final String signature,
 104         final String[] exceptions)
 105     {
 106         super(api, access, name, desc, signature, exceptions);
 107         this.mv = mv;
 108     }
 109 
 110     @Override
 111     public void visitEnd() {
 112         // Compares TryCatchBlockNodes by the length of their "try" block.
 113         Comparator<TryCatchBlockNode> comp = new Comparator<TryCatchBlockNode>() {
 114 
 115             public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) {
 116                 int len1 = blockLength(t1);
 117                 int len2 = blockLength(t2);
 118                 return len1 - len2;
 119             }
 120 
 121             private int blockLength(TryCatchBlockNode block) {
 122                 int startidx = instructions.indexOf(block.start);
 123                 int endidx = instructions.indexOf(block.end);
 124                 return endidx - startidx;
 125             }
 126         };
 127         Collections.sort(tryCatchBlocks, comp);




 128         if (mv != null) {
 129             accept(mv);
 130         }
 131     }
 132 }


  49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  51  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  52  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  53  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  54  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  55  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  56  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  57  * THE POSSIBILITY OF SUCH DAMAGE.
  58  */
  59 
  60 package jdk.internal.org.objectweb.asm.commons;
  61 
  62 import java.util.Collections;
  63 import java.util.Comparator;
  64 
  65 import jdk.internal.org.objectweb.asm.MethodVisitor;
  66 import jdk.internal.org.objectweb.asm.Opcodes;
  67 import jdk.internal.org.objectweb.asm.tree.MethodNode;
  68 import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode;
  69 import jdk.internal.org.objectweb.asm.tree.TypeAnnotationNode;
  70 
  71 /**
  72  * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers
  73  * are sorted in a method innermost-to-outermost. This allows the programmer to
  74  * add handlers without worrying about ordering them correctly with respect to
  75  * existing, in-code handlers.
  76  *
  77  * Behavior is only defined for properly-nested handlers. If any "try" blocks
  78  * overlap (something that isn't possible in Java code) then this may not do
  79  * what you want. In fact, this adapter just sorts by the length of the "try"
  80  * block, taking advantage of the fact that a given try block must be larger
  81  * than any block it contains).
  82  *
  83  * @author Adrian Sampson
  84  */
  85 public class TryCatchBlockSorter extends MethodNode {
  86 
  87     public TryCatchBlockSorter(final MethodVisitor mv, final int access,
  88             final String name, final String desc, final String signature,
  89             final String[] exceptions) {
  90         this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);





  91     }
  92 
  93     protected TryCatchBlockSorter(final int api, final MethodVisitor mv,
  94             final int access, final String name, final String desc,
  95             final String signature, final String[] exceptions) {






  96         super(api, access, name, desc, signature, exceptions);
  97         this.mv = mv;
  98     }
  99 
 100     @Override
 101     public void visitEnd() {
 102         // Compares TryCatchBlockNodes by the length of their "try" block.
 103         Comparator<TryCatchBlockNode> comp = new Comparator<TryCatchBlockNode>() {
 104 
 105             public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) {
 106                 int len1 = blockLength(t1);
 107                 int len2 = blockLength(t2);
 108                 return len1 - len2;
 109             }
 110 
 111             private int blockLength(TryCatchBlockNode block) {
 112                 int startidx = instructions.indexOf(block.start);
 113                 int endidx = instructions.indexOf(block.end);
 114                 return endidx - startidx;
 115             }
 116         };
 117         Collections.sort(tryCatchBlocks, comp);
 118         // Updates the 'target' of each try catch block annotation.
 119         for (int i = 0; i < tryCatchBlocks.size(); ++i) {
 120             tryCatchBlocks.get(i).updateIndex(i);
 121         }
 122         if (mv != null) {
 123             accept(mv);
 124         }
 125     }
 126 }