Работа с исключениями Try/Catch в байткоде Java? ("Несоответствие высоты стека")

Я пытаюсь сделать некоторую обработку ошибок в байткоде 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?

6
задан Jack 12 December 2011 в 22:45
поделиться