7

Haskell を使用して Java バイトコード パーサーを作成しましたが、問題なく動作します。しかし、次のステップで私は完全に困惑しました。

私の Haskell プログラムは、実行時に Java プログラムが出力するように .class ファイルを変更する必要があります。

メソッドを実行する前に「[ここにメソッド名] を入力」し、

メソッドを実行した後、「[ここにメソッド名] を終了します」。

私が知っているのは、定数プールとメソッド テーブルに への呼び出しを追加する必要があるということSystem.out.printlnだけですが、まだ何かが足りないと感じています。

  • この問題にアプローチする最善の方法は何ですか?
  • System.out.printlnバイトコード で呼び出す方法をどのように知っていますか?
  • 後で引数として呼び出されるように、メソッドの名前を含む文字列をどのように保存しますSystem.out.printlnか?
4

4 に答える 4

2

これは、さまざまなバイト コード エンジニアリング ライブラリが提供するものです。ASM、BCELなど。宿題の詳細はアスペクトであり、AspectJはまさにそれを行います。

宿題は Haskell バイト コード エンジニアリング演習を作成することのように聞こえるので、クラス ファイルを自分で変更する必要があります。上記の@biziclopによる提案は正しいです。クラス ファイルに対して before と after を実行し、デルタに注意して、Haskell から自分で同じことを行います。

[ps: もちろん、上記の「ショートカット」 :P は、JVM 仕様 (q へのコメントに記載されているように) を読みたくない場合や、 Java コンパイラ。基本的に、invoke 用のさまざまなバイト コードの 1 つ (ここではインターフェイス メソッド呼び出し) を使用してメソッドを呼び出します。その前に、クラス System の静的フィールドやスタック上のメソッド名などのレシーバーが必要です。詳細はスペックに記載】

于 2012-04-20T21:11:49.920 に答える
2

Java バイトコード リストを取得し、System.out.println() への関数呼び出しだけで単純なコンパイル済みクラスをポップして開き、覗いてみてください。必要なメソッドに対してこれを行います。これを見つける最善の方法は、いくつかの単純なコード ファイルを使用して調査を行い、作業を進めながらリバース エンジニアリングを行うことです。必要なメッセージをユニコードに変換し、それを関数に渡す必要があります。その部分も忘れないでください。バイトコードを征服するための探求に役立つさまざまなプログラムがあります。

于 2012-04-20T21:24:08.247 に答える
2

おそらく最も簡単な方法は、コードを含む単一のメソッドを持つ Java クラスを作成System.out.println()し、それをコンパイルしてjavac結果を観察することです。

慣れてきたら、一歩一歩進んでください。

  1. System.out.println()計測する Java ファイルのどこかに呼び出しを追加します。これにより、定数プールが処理されます。関連する定数を見つけてバイトコードを挿入する Haskell コードを作成します。
  2. Java ファイルから「crutch」呼び出しを削除し、Haskell で定数プール操作を実装します。
于 2012-04-20T21:03:41.247 に答える
0

Javassistこの問題に取り組む最善の方法は、ライブラリ ( Java Programming Assistant )を使用することだと思います。 Javassist.bytecodeクラスには、便利な機能がいくつかあります。

于 2012-05-13T06:15:26.413 に答える