处理Java字节码中的Try/Catch异常?("堆栈高度不一致")

Jac*_*ack 6 java bytecode exception try-catch jasmin

我试图在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
Run Code Online (Sandbox Code Playgroud)

上面的问题是当我有多个指令跳转到这个子程序时,我在运行字节码时收到一条错误信息,说堆栈高度不一致.

也许使用例外是解决这个问题的最佳方法?

通过一些谷歌搜索,我发现你可以创建Exception类的实例,并用以下内容初始化它们:

new java/lang/Exception
dup
ldc "exception message!"
invokespecial java/lang/Exception/<init>(Ljava/lang/String;)V
Run Code Online (Sandbox Code Playgroud)

我也发现你可以扔它们,athrow这似乎没问题.

然而令我感到困惑的是如何捕获异常.似乎有一个神奇的"异常表"将异常的抛出和捕获粘在一起,但我不知道如何从头开始编写字节码(以及使用Jasmin进行汇编)时定义其中一个.有人可以告诉我创建异常表的秘诀吗?并且可能给我一个与jasmin汇编的异常处理示例?

Jac*_*ack 2

最后我想出了一个比在 Jasmin 中jsr使用定义方法更好的解决方案.method。我只是invokestatic在检测到错误后调用错误处理程序。

对于那些寻找实际异常处理的人 - 我认为在 Jasmin 中定义异常表可以使用 来完成.catch,但我还没有研究它,因为方法定义解决了我的问题。

编辑:

我最后还是看了.catch一遍,发现真的很好用。它被记录在这里