Skip to content

Instantly share code, notes, and snippets.

@sampsyo
Created January 19, 2010 20:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sampsyo/281277 to your computer and use it in GitHub Desktop.
Save sampsyo/281277 to your computer and use it in GitHub Desktop.
fix for exception handler ordering in ASM
import java.util.Collections;
import java.util.Comparator;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
/**
* Sorts the exception handlers in a method innermost-to-outermost. This
* allows the programmer to add handlers without worrying about ordering them
* correctly with respect to existing, in-code handlers.
*
* Behavior is only defined for properly-nested handlers. If any "try" blocks
* overlap (something that isn't possible in Java code) then this may not
* do what you want.
*/
public class HandlerSorterAdapter extends MethodNode {
private final MethodVisitor mv;
public HandlerSorterAdapter(
final MethodVisitor mv,
final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions)
{
super(access, name, desc, signature, exceptions);
this.mv = mv;
}
public void visitEnd() {
TryCatchBlockLengthComparator comp =
new TryCatchBlockLengthComparator(this);
Collections.sort(tryCatchBlocks, comp);
if (mv != null) {
accept(mv);
}
}
}
/**
* Compares TryCatchBlockNodes by the length of their "try" block.
*/
class TryCatchBlockLengthComparator implements Comparator {
private final MethodNode meth;
public TryCatchBlockLengthComparator(MethodNode meth) {
this.meth = meth;
}
public int compare(Object o1, Object o2) {
int len1 = blockLength((TryCatchBlockNode)o1);
int len2 = blockLength((TryCatchBlockNode)o2);
return len1 - len2;
}
private int blockLength(TryCatchBlockNode block) {
int startidx = meth.instructions.indexOf(block.start);
int endidx = meth.instructions.indexOf(block.end);
return endidx - startidx;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment