通过一些演示,我遇到了以下声明:当JVM加载一个类时,它可以分析其内容并确保没有操作数堆栈的溢出或下溢。我发现a lot of sources提出了同样的主张,但没有说明它是如何完成的。
我不清楚如何使用静态分析进行此类验证。假设我有一个(恶意)方法,它可以获得一些值作为参数,并使用它来执行一系列弹出。在加载时,迭代次数是未知的,因为它取决于方法调用者给出的参数。因此,在我看来,只有在运行时才能确定是否会出现下溢。我在这里缺少什么?
答案 0 :(得分:10)
您可以在Java Virtual Machine specification中找到字节码验证器的基本描述。
简单来说,堆栈深度在每个分支点都是已知的,并且在同一个合并点合并的两个执行路径也必须具有相同的堆栈深度。因此,验证者不允许您在没有相应的放置的情况下执行一系列弹出。
答案 1 :(得分:5)
该方法的代码被分成执行块。 “块”是一系列指令,可以在不跳出或跳入的情况下执行。这些块构建了所有可能执行路径的有向图。
一个块总是期望一个堆栈大小在它的开头,并且在它的末尾有一个固定的堆栈大小(开始+所有推送 - 所有pops)。验证器检查对于从给定块'b'可以到达的所有块'a',b的结束堆栈大小匹配a的起始堆栈大小。