JVM exceptions are weird: a decompiler perspectiveNovember 2, 2025 Hacker News LobstersSome time ago, I played around with decompiling Java class files in a more efficient manner than traditional solutions like Vineflower allow. Eventually, I wrote an article on my approach to decompiling control flow, which was a great performance boost for my prototype.At the time, I believed that this method can be straightforwardly extended to handling exceptional control flow, i.e. decompiling try鈥atch blocks. In retrospect, I should鈥檝e known it wouldn鈥檛 be so easy. It turns out that there are many edge cases, ranging from strange javac behavior to consequences of the JVM design and the class file format, that significantly complicate this. In this post, I鈥檒l cover these details, why simple solutions don鈥檛 work, and what approach I鈥檝e eventually settled on.JVM is a stack-based language. The majority of instructions interact exclusively with the stack, e.g. iadd pop two integers off the top of the stack and pushes their sum back. A small handful of instructions, like if_icmpeq, transfer control to a given address based on whether a primitive condition holds (e.g. value1 == value2 in this case). That is sufficient to implement if, while, and many other explicit control flow constructs.Exceptional control flow, however, is implicit, so it cannot be handled the same way. A single try block should catch all exceptions arising in its region, be that exceptions forwarded from a method call in invokevirtual, division by zero in idiv, or null pointer dereference in getfield. Such relations cannot be efficiently encoded in the bytecode itself, so they are stored separately in the exception table.Each entry of the exception table specifies which region of instructions is associated with which exception handler. If an exception is raised within such a region, the stack is cleared, the exception object is pushed onto the stack, and control is transferred to the first instruction of the han...
First seen: 2025-11-09 22:26
Last seen: 2025-11-16 11:57