Как JVM может проверить, нет ли операндов при загрузке класса?

Перейдя к некоторому представлению, я столкнулся с следующим утверждением: когда JVM загружает класс, он может анализировать его содержимое и убедиться, что нет переполнения или недостаточного стека стека операндов. Я нашел много источников, которые делают одно и то же утверждение, но не указав, как это делается.

Мне непонятно, как такая проверка может быть выполнена с использованием статического анализа. Скажем, у меня есть (злонамеренный) метод, который получает некоторое значение в качестве аргумента и использует его для выполнения серии попсов. Во время загрузки количество итераций неизвестно, так как это зависит от аргумента, данного вызывающим методом. Поэтому мне кажется, что только во время выполнения можно будет определить, будет ли поток или нет. Что мне здесь не хватает?

Ответы

Ответ 1

Вы можете найти базовое описание верификации Bytecode в спецификации виртуальной машины Java.

Проще говоря, глубина стека известна в каждой точке ветвления, а два пути выполнения, сливающиеся в одной точке слияния, также должны иметь одинаковую глубину стека. Таким образом, верификатор не позволит вам выполнять серию попсов без соответствующих пометок.

Ответ 2

Код метода разбивается на блоки выполнения. "Блок" представляет собой последовательность инструкций, которые могут выполняться без выпрыгивания или вхождения. Блоки строят ориентированный график всех возможных путей выполнения.

Блок всегда ожидает определенного размера стека с самого начала и имеет фиксированный размер стека в конце (начало + все нажатия - все всплывающие окна). Верификатор проверяет, что для всех блоков "a", которые могут быть достигнуты из заданного блока "b", размер конечного стека b соответствует начальному размеру стека.