总结:使用 ASM,给定一个字节码类,对于每个方法指令(MethodInsnNode),我需要获取正在使用的引用。
考虑以下类:
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());
}
考虑以下生成的字节码指令:
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
}
我试图找出一种方法来获取使用 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
. 确切的堆栈跟踪将像这样,它由包含“prev”属性的实际指令组成,该属性将是已被调用以加载该变量的方法:
问题是我们有所有者属性,名称属性,但我无法获得对该对象的引用。在以下情况下:
Boolean myBool2 = true;
Cemo cemo = new Cemo();
assertTrue(cemo.isTrue());
我需要在 ASM 中引用“cemo”对象。
到目前为止我已经尝试过: - 获取框架对象,但它只包含变量“插槽”,没有引用。- 分析MethodInsnNode
前面的指令。
我应该如何做到这一点?