Определение одной конкретной локальной переменной
Допустим, у меня есть класс, экземпляр которого должен быть передан всем методам, либо через аргумент, либо через функцию получения.
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;
}
}
Причина существования метода получения заключается в том, что аргументы некоторых методов не могут быть изменены без нарушения политик безопасности 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, чтобы получить индекс, который мне нужен для второго запуска.
Однако, узнав, что я могу выполнять исключение / встраивание вызова метода, не прибегая к такому двухпроходному подходу, я неохотно делаю это сейчас.
(Я тоже понимаю visitLocalVariable
быть просто отладочной информацией, но поскольку она включает в себя фактические индексы, она не должна быть такой же проблематичной, как в вопросе, связанном с.)
Есть ли способ избежать двух проходов?