Going over some presentation, I’ve come across the following claim: When the JVM loads a class, it can analyze its content and make sure there’s no overflow or underflow of the operand stack. I’ve found a lot of sources that make the same claim, but without specifying how it’s done.
It is unclear to me how such verification can be made using static analysis. Say I have a (malicious) method that gets some value as an argument, and uses it to perform a series of pops. At load time, the number of iterations is not known, as it depends on the argument given by the method’s caller. Therefore, it seems to me that only at runtime should it be possible to determined whether there will be an underflow or not. What am I missing here?
You can find basic description of the Bytecode Verifier in Java Virtual Machine specification.
To put it simple, stack depth is known at every branching point, and two execution paths merging at the same merge point must also have the same stack depth. So, the verifier won’t allow you to perform series of pops without corresponding puts.