Я пытаюсь сделать некоторую обработку ошибок в байткоде java. Сначала я попытался реализовать некоторые catch-подобные подпрограммы, где я бы проверял условие ошибки и переходил к соответствующей подпрограмме, примерно так:
iconst_1
iconst_0
dup
ifeq calldiverr
goto enddivtest
calldiverr:
jsr divError
enddivtest:
idiv
...More instructions...
divError:
getstatic java/lang/System/out Ljava/io/PrintStream;
ldc "Oh dear you divided by 0!"
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
Проблема с вышеуказанным заключается в том, что когда у меня есть несколько инструкций, которые переходят к этой подпрограмме, я получаю сообщение об ошибке при выполнении байткода, говорящее, что высота стека несовместима.
Возможно, использование исключений - лучший способ обойти это?
Погуглив, я обнаружил, что можно создавать экземпляры классов Exception и инициализировать их чем-то вроде:
new java/lang/Exception
dup
ldc "exception message!"
invokespecial java/lang/Exception/<init>(Ljava/lang/String;)V
Я также обнаружил, что их можно бросать с помощью athrow
, и это кажется нормальным.
Однако меня смущает то, как именно отлавливаются исключения. Кажется, существует магическая "таблица исключений", которая склеивает бросание и ловлю исключений вместе, но я не знаю, как определить такую таблицу при написании байткода с нуля (и сборке с помощью Jasmin). Может ли кто-нибудь раскрыть мне секрет создания таблицы исключений? И, возможно, привести пример обработки исключений, который можно собрать с помощью jasmin?