识别一个特定的局部变量

时间:2017-12-07 10:15:41

标签: java bytecode instrumentation java-bytecode-asm

假设我有一个类,必须通过参数或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仅仅是调试信息,但由于它包含实际索引,因此它不应该像链接到的问题那样有问题。)

有没有办法避免两次通过?

0 个答案:

没有答案