如何在ASM中通过核心api获取maxLocals?

时间:2019-05-28 12:17:44

标签: java bytecode java-bytecode-asm

我想获取maxLocals来存储数据,例如

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

tree apithis.nextLocals = methodNode.maxLocals; 但是核心api没什么。

注入biz〜周围的错误方法。

像这样:

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

现在我能够成功注入字节码,但有时由于我无法获取maxLocal而出错。

1 个答案:

答案 0 :(得分:2)

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

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

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

处理注入的代码时,您只需要在原始方法的访问者(编写者)上调用visitor方法,因为LocalVariablesSorter上的访问者方法将被原始代码调用并进行转换。另请参见this answerthat answer