6

Javaバイトコードでエラー処理を行おうとしています。私は最初に、いくつかのキャッチのようなサブルーチンを実装しようとしました。そこでは、エラー状態をチェックし、適切なサブルーチンにジャンプします。

  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を使用して組み立てる)ときにこれらの1つを定義する方法がわかりません。誰かが例外テーブルを作成する秘訣を教えてもらえますか?そして、おそらくジャスミンでアセンブルされる例外処理の例を教えてください。

4

3 に答える 3

2

結局、私は、Jasminでjsr使用するメソッドを定義するよりも優れた解決策を思いつきました。エラーを検出したら、エラーハンドラーを呼び出していました.methodinvokestatic

実際の例外処理を探している人のために-Jasminで例外テーブルを定義することは、を使用して行うことができると思いますが.catch、メソッド定義が私の問題を解決したので、私はそれを調べていません。

編集:

私は.catch最終的に見なければなりませんでした、そしてそれが本当に使いやすいとわかりました。ここに文書化されています。

于 2011-12-13T17:22:29.057 に答える
0

まず、バージョン51.0のクラスファイルにjsr命令が含まれていない可能性があることを指摘する価値があります。コードを繰り返すか、メソッドを使用します。

バイトコードのすべてのポイントで、フレーム内のすべての要素の静的タイプを知る必要があります。各フレームはコールスタックではありません。

一般的に、あなたは巨大な大きなスタックで遊んでみたいとは思わないでしょう。物事を単純に保つために、一時変数をローカル変数に格納します。

例外がスローされた場合、明らかに、フレームには、例外がスローされた可能性のある任意の場所からのコンテンツが含まれている可能性があります。そのため、内容は破棄され、例外に置き換えられます。とにかく、フレームの内容を使用するために戻って再開することはできません。

于 2011-12-12T23:32:58.973 に答える
0

検証のルールjsrはかなり複雑であり、トムが示したように、オペコードは非推奨です。したがって、避けるのが最善です。

私の記憶jsrは少し曖昧ですが...

(更新)Javaバイトコード検証には、2つの制御フローが結合する場合は常に、スタックの深さが両方のブランチで同一でなければならないという規則があります。 jsrサブルーチンはこのルールからポイントまで免除されます。スタックの深さが異なる複数の例外ポイントは同じルーチンに「到達」できますが、ルーチンのエントリから後続のエントリまでのjsrスタックの深さの正味の変化はゼロ(または実際にはマイナス1)である必要があります。原因は常にルーチンへのエントリ時にプッシュされます)。jsrret

さらに、jsrルーチンは「エスケープ」して通常の制御フローに戻ることができますが、そうする場合、jsrはジョインポイントのスタック深度ルールから除外されません。jsrルーチンは異なるスタック深度で入力される可能性があるため、これにより、これを実行できる状況が大幅に制限されます。

(そして、私はまだそのいくつかが間違っていることは間違いありませんが、それは私ができる最善のことです。)

jsr(例外を除いて、問題を「回避」する方法がよくわかりません。)

(また、Sunはバイトコードの記述を4または5ではるかに複雑にし(どちらを思い出せないか)、バイトコードを手動でコーディングすることをほとんど不可能にしました。それ以外の場合はIBMのベリファイアですが、それは別の問題です。)

于 2011-12-13T01:55:33.240 に答える