2

私はJavaバイトコードにかなり慣れていません。BCEL を使用してバイトコードを生成していますが、生成されたコードを使用しようとするとエラー メッセージが表示されます。(後から考えると、ObjectWeb ASM は BCEL よりも高度で、より一般的に使用されているようです。)

エラーメッセージは次のとおりです。

Exception in thread "main" java.lang.VerifyError: 
(class: cb/io/FileDescriptor, method: set 
 signature: (I)J) 
Stack size too large

メソッドは次のとおりです。

// Method descriptor #4 (I)J
// Stack: 0, Locals: 1
private static long set(int arg1);
  0  lconst_0
  1  lreturn
    Local variable table:
      [pc: 0, pc: 2] local: arg1 index: 0 type: int

私が理解していることから、入力パラメーターと一致するため、ローカル変数テーブルは正しいです。メソッドが静的であるため、「this」変数を追加していません。

私が間違っていなければ、lconst_0 は long 値 0 をスタックにロードし、lreturn はその値を消費して返します。

私は何を間違っていますか?ここに伝えるのに十分な情報はありますか?

ありがとう!

4

1 に答える 1

7

すべてのJavaメソッドに使用する最大スタックサイズを宣言する必要があります。たとえば、ASMは値を自動的に計算できるため、多くの手間を省くことができます。最大スタックサイズは、メソッドで使用するスロットの絶対最大量です(一度に、累積されません)。分岐を行う場合、計算は非常に難しい場合があります。

longここで値をロードしているので、 longsは2つのスタックスロットを消費します(実際、64ビット値(ポインターを除く)ごとに2つのスタックスロットを消費します)。したがって、ここで最大スタックサイズを2に設定する必要があります。

Stack size too large、メソッド記述子で指定されているように、メソッドがより多くのスタックスロットを消費することを示しています。

于 2013-03-07T12:09:37.020 に答える