Определение одной конкретной локальной переменной

Допустим, у меня есть класс, экземпляр которого должен быть передан всем методам, либо через аргумент, либо через функцию получения.

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 быть просто отладочной информацией, но поскольку она включает в себя фактические индексы, она не должна быть такой же проблематичной, как в вопросе, связанном с.)

Есть ли способ избежать двух проходов?

0 ответов

Другие вопросы по тегам