-1

要約:ASMを使用して、各メソッド命令(MethodInsnNode)に対してバイトコードクラスを指定すると、それに使用されている参照を取得する必要があります。ASMで参照を取得するには?

Code: 
    0: aload_0 
    1: invokespecial #1     // Method java/lang/Object."<init>":()V 
    4: return 



public void myMethod(); 
    Code: 
     0: ldc   #2     // String str12 
     2: astore_1 
     3: aload_1 
     4: astore_2 
     5: ldc   #3     // String str3 
     7: astore_3 
     8: iconst_1 
     9: invokestatic #4     // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean; 
     12: astore  4 
     14: iconst_1 
     15: invokestatic #4     // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean; 
     18: astore  5 
     20: new   #5     // class com/devfactory/utqg/analysis/InstrumentationClass$Cemo 
     23: dup 
     24: aconst_null 
     25: invokespecial #6     // Method com/devfactory/utqg/analysis/InstrumentationClass$Cemo."<init>":(Lcom/devfactory/utqg/analysis/InstrumentationClass$1;)V 
     28: astore  6 
     30: aload_0 
     31: aload   6 
     33: invokevirtual #7     // Method com/d/utqg/analysis/InstrumentationClass$Cemo.isTrue:()Z 
     36: invokestatic #4     // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean; 
     39: invokespecial #8     // Method assertTrue:(Ljava/lang/Boolean;)V 
     42: aload_0 
     43: aload   6 
     45: invokevirtual #7     // Method com/d/utqg/analysis/InstrumentationClass$Cemo.isTrue:()Z 
     48: invokestatic #4     // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean; 
     51: invokespecial #8     // Method assertTrue:(Ljava/lang/Boolean;)V 
     54: return 
} 

私はオブジェクト参照を取得する方法の方法を把握しようとしている次の生成バイトコード命令を考慮

public void myMethod(){ 
String str1 = "str12"; 
String str2 = str1; 
String str3 = "str3"; 
Boolean myBool = true; 
Boolean myBool2 = true; 
Cemo cemo = new Cemo(); 
assertTrue(cemo.isTrue()); 

assertTrue(cemo.isTrue()); 

}

:以下のクラスを考慮し

ASMを使用して呼び出されています。バイトコードレベルでは、INVOKESPECIAL命令が呼び出されるたびに、前に使用される値がロードされます。例:

31: aload   6  //Loading the value stored in 6 position 
     33: invokevirtual #7     // Method com/d/utqg/analysis/InstrumentationClass$Cemo.isTrue:()Z 

ここには参考までにあります。しかし、ASMでは、thisへの参照はありません。問題は、私たちということです

Sample of inspected element

:正確にスタックトレースは、それがその変数をロードするために呼び出されたメソッドとなります「PREV」のattrを含む実際の命令によって構成されています、この1のようになります所有者属性name属性がありますが、そのオブジェクトへの参照を取得できません。次の場合:

Boolean myBool2 = true; 
Cemo cemo = new Cemo(); 
assertTrue(cemo.isTrue()); 

ASMの「cemo」オブジェクトへの参照が必要です。

これまでに試したことは次のとおりです。 - フレームオブジェクトを取得しますが、変数 "slots"のみが含まれており、参照はありません。 - 前の手順をMethodInsnNodeで分析してください。

どうすればよいですか?

答えて

3

JVMはスタックマシンです。つまり、メソッドは常に、非スタティックメソッドの最初の暗黙の引数であるオペランドスタックの先頭の値で呼び出されます。あなたが計画していることを実行するには、オペランドスタックのすべての引数をいつでも追跡して、バイトコードでメソッド呼び出しを処理したら、現在どの値がthisに満たされているかを判断する必要があります。

これは、メソッドの任意の命令を処理し、現在どのレジスタおよびスタックスロットがどのオブジェクトを参照しているかを追跡する必要があることを意味します。限られた方法で、メソッドを呼び出すインスタンスを追跡することができます。しかし、Java(バイトコード)プログラムは、Javaプログラミング言語以外の制約を課し、コード内の任意のジャンプを可能にするので、非常に複雑になる可能性があることに注意してください。基本的には、いつどのようなメソッドが実行されるかを知るためには、一般的なケースのメソッド呼び出しをエミュレートする必要がありますので、むしろ難しいものに設定されています。

+0

あなたの答え、ラファエルに感謝します:)。私はそれを調査します。ところで、あなたは、ASTの分析を使用することは、その問題の良いアプローチだと思いますか?これらのクラスのソースコードもあります。 –

+0

ASTを使用する大きな利点の1つは、書式設定を気にする必要がないことです。ソースコードの利点は、任意のフロー制御ができないことです。メソッド呼び出し時にインスタンスを抽出するための計測メソッドを検討しましたか?実行時にこの情報を調べることができます。 –

関連する問題