Don't split interval for exception table entry on dead code
It's very weird code in MethodWriter.computeAllFrames with splitting interval for exception table entry:
/** Computes all the stack map frames of the method, from scratch. */
private void computeAllFrames() {
...
// Loop over all the basic blocks and visit the stack map frames that must be stored in the
// StackMapTable attribute. Also replace unreachable code with NOP* ATHROW, and remove it from
// exception handler ranges.
...
firstHandler = Handler.removeRange(firstHandler, basicBlock, nextBasicBlock);
...
}
- According to this logic actual exception table doesn't correspond to created one through ASM api
- For compiler it's implies the correspondence beetween source code and bytecode is broken
- As result of 2 it will break decompilers
- On simple processing class files with dead code in try interval ASM will produce not equivalent bytecode at least in exception table (for simple transformation: input -> ClassWriter(ClassReader(input)) -> output)
Such splitting behaviour could be reproduced with Kotlin compiler 1.3.11 on next code:
fun takeWhileSize(initialSize: Int , block: (String) -> Int) {
val current = "PARAM"
try {
if (1 >= initialSize) {
try {
block(current)
} finally {
val i = "INNER FINALLY"
}
} else {
val e = "ELSE"
}
} finally {
val o = "OUTER FINALLY"
}
}