首页 > 解决方案 > 如何通过 ASM 中的核心 api 获取 maxLocals?

问题描述

我想获取maxLocals存储数据,比如

int index = mv.visitLocalVariable(name, desc, null, start, end, ++maxLocals);

by tree apithis.nextLocals = methodNode.maxLocals; 但 core api ,什么都没有。

biz周围的注入out、error方法~。

像这样:

@Test
    public void testCode() {
        hooK hook = StatisGet.get(1L);
        hook.into();
        try {
            //biz
            hook.out();
        } catch (Throwable e) {
            hook.error(e);
        }
    }

现在我能够成功注入字节码,但有时会出错,因为我无法获得 maxLocal。

标签: javabytecodejava-bytecode-asm

解决方案


假设“核心 API”是指访问者 API,则在visitMaxs上存在方法MethodVisitor,该方法将使用最大堆栈数和局部变量数调用。

但是有一个问题; 此方法将在其他访问者方法之后调用。因此,您不能事先使用该数字来查找未使用的局部变量。

一个解决方案是使用适配器,LocalVariablesSorter如果您认为它是“核心 API”的一部分。它允许您在需要一个空闲的局部变量时调用newLocal它,它会告诉您到目前为止尚未遇到的下一个变量号。然后它会记住编号,如果在继续访问原始代码时遇到冲突的变量编号使用,它将重新编号这些变量编号,以解决冲突。

在处理注入的代码时,您只需要关心调用原始方法访问者(编写器)上的访问者方法,LocalVariablesSorter因为原始代码上的访问者方法将被调用并进行转换。另见这个答案那个答案


推荐阅读