Некоторое время назад я спросил в Embed the existing code of a method in a try-finally block, как обернуть тело метода в блок try-finally, используя ASM. Решение заключалось в том, чтобы посетить метку блока try в начале тела метода в visitCode()
и завершить блок try-finally при посещении инструкции с кодом возврата с номером visitInsn()
. Я знал, что решение не будет работать, если метод не имеет инструкции возврата, которая применяется, если метод всегда оставляет исключение.Вставить существующий код метода в блок try-finally (2)
Хотя, я обнаружил, что прежнее решение иногда не подходит для методов с инструкциями возврата. Он не будет работать, если метод имеет несколько команд возврата. Причина в том, что он генерирует недействительный байт-код, потому что в начале метода добавляется один блок try-finally, но завершается более одного блока try-finally.
Обычно (но, возможно, в зависимости от компилятора javac), метод байт-кода содержит одну команду возврата, и все пути возврата заканчиваются на этой инструкции, перепрыгивая туда. Тем не менее, составление следующего кода с Eclipse, приведет к байт-код с двумя инструкциями возврата: код
public boolean isEven(int x) {
return x % 2 == 0;
}
байт, собранных с Eclipse:
0: iload_1
1: iconst_2
2: irem
3: ifne 8
6: iconst_1
7: ireturn // javac compilation: goto 9
8: iconst_0
9: ireturn
Таким образом, я задаюсь , что такое правильный способ для обертывания всего кода кода метода.
Обратите внимание, что перенаправлять все возвращается к одной точке также означает, что вы должны убедиться, что высоты стека равны. Если вы только преобразуете обычный скомпилированный Java-код, они, вероятно, уже будут, но это еще одна проблема, о которой нужно помнить. – Antimony
@Antimony: правильно, и если вы не используете встроенную функцию вычисления структуры ASM, есть еще больше работы. Вот почему я рекомендую решение для замены и замены. – Holger
Благодарим вас за ответ. Я не уверен, что это хорошая идея пойти на простое решение делегирования, потому что я касаюсь каждого метода кода, и я буду выполнять дальнейшие шаги анализа байт-кода, которые должны были бы обнаружить и пропустить методы делегирования. Думаю, я попытаюсь ввести несколько блоков (в примере от 0 до 7 и 8-9). Идея о замене всех возвратов прыжком на один возврат тоже звучит хорошо, но он не охватывает явно заброшенные исключения ('' ATHROW''). – nrainer