假设我有一个类,必须通过参数或getter函数将其实例传递给所有方法。
package asmvisit;
public class B {
public void foo(int x, Crucial c){
c.value = x;
}
public void bar(int c){
Crucial crucial = Crucial.get();
crucial.value = c;
}
}
getter存在的原因是某些方法的参数在不违反java安全策略(即崩溃)的情况下无法修改。
我知道正在处理的Crucial
实例可能会在方法执行期间发生变化,但如果确实如此,则专用局部变量将始终保持对它的引用。因为这些是通过仪器插入的,所以我不能依赖它在所有方法中具有相同的名称。
我应能够依赖它作为第一个分配了Crucial
对象的局部变量。
然后,这个想法就是确定它的确如此。
如果这是一个论点,那么我应该能够轻松识别使用 Types.getArgumentTypes - 例如
public class MyClassVisitor extends ClassVisitor {
public MyClassVisitor(ClassVisitor cv) {
super(Opcodes.ASM5, cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
Type[] argtypes = Type.getArgumentTypes(desc);
String argtypeString = Arrays.toString(argtypes);
System.out.println(String.format("argtypes = %s",argtypeString));
String targetType = "Lasmvisit/Crucial;";
int index;
if(argtypeString.contains(targetType)){
index = ((access & Opcodes.ACC_STATIC) == 0 ? 1 : 0); //"this" is not included in {@code argtypes}
for(Type t : argtypes){
if(t.toString().equals(targetType)) break;
else index += ((t.equals(Type.DOUBLE_TYPE) || t.equals(Type.LONG_TYPE)) ? 2 : 1);
}
}else index = -1;
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if(mv != null){
return new MyMethodVisitor(api,mv, index);
}
return mv;
}
}
现在,如果new MyMethodVisitor(api,mv, index);
收到非负index
,那么它就会使用它。
另一方面,如果它确实收到否定的index
,那么我们的想法是覆盖某些,以便在我们遍历代码时进行检测。
当然,我可以选择两个版本,在第一个版本中,我使用visitLocalVariable来获取第二次运行所需的索引。
然而,在得知I can do method call elimination / inlining without having to resort to such a two-pass approach后,我现在不愿意这样做。
(我也理解visitLocalVariable
仅仅是调试信息,但由于它包含实际索引,因此它不应该像链接到的问题那样有问题。)
有没有办法避免两次通过?