Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
Introduce control flow verification. #213
This is something I've wanted to do for years, and @peace-maker finally convinced me to do it. SourcePawn needs some internal concept of a control-flow graph. It is the gateway to many important optimizations and transformations, and it will also make our method verification much more rigorous. In fact, it is not possible to attempt many optimizations without veracity.
This patch introduces the
I used a corpus of ~6,000 .smx files from the forums and web compiler and confirmed that no new verification failures were introduced, which is a good sign for our scrappy compiler (so far). The time to verify these methods did not significantly change despite the new passes involved, but that may change in the future as we expand verification.
The prescan step runs through the code stream and ensures it can actually be decoded. That is, the code stream does not terminate in the middle of an instruction. It also computes the actual bounds of the method, and verifies jump and switch instructions. Finally, along the way, it computes two important pieces of information:
The scan step is a fairly simple breadth-first algorithm to build a
The cleanup step iterates all blocks looking for any that were not terminated. In theory, this could only happen on at most one block - and only if the method is malformed (for example, does not contain a
In debug builds it also verifies that no disconnected blocks exist. Since it is a graph algorithm, all blocks should be connected.
This introduces three new data structures. The first is ControlFlowGraph, which represents a collection of basic blocks for a method. A basic block is a unit of code that terminates in a control flow instruction, and for which the only entry point is the start of the block. Basic blocks are represented by the new Block class. Finally, there is a new GraphBuilder class which can extract a ControlFlowGraph for a method. It also performs basic verification on control-flow, namely: - Jump targets must be a valid decoded instruction in the method. - The method's local control flow does not escape the method bounds.