如何在使用asm库进行检测的方法中查找空局部变量

时间:2012-07-26 12:37:42

标签: java bytecode instrumentation java-bytecode-asm

为其不同方法检测类时为了使方法在文本文件中执行写操作。我首先将字符串存储在显式定义的局部变量3160中。如何选择这些变量以防止与现有变量冲突。

与此代码段类似,代码执行每次进入任何方法时将类名写入文本文件的工作。为了做到这一点,必须使用变量3160将字符串s加载到堆栈上(值保持较大,以便已定义的变量名称不与变量s(3160)冲突。我的问题是如何在方法中定义局部变量在ASM图书馆的仪器仪表中。这个问题对许多人来说似乎还为时过早,但那是因为我是初学者。

    String s= className;
    mv.visitLdcInsn(s);
    mv.visitVarInsn(Opcodes.ASTORE, 3160);
    mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
    mv.visitInsn(Opcodes.DUP);
    mv.visitVarInsn(Opcodes.ALOAD, 3160);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/me/database/dataCollectionFile/Info", "callMeAnyTime", "()Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");

3 个答案:

答案 0 :(得分:2)

您应该使用LocalVariablesSorter适配器(从中扩展您自己的访问者,或者在MethodWriter之前将其添加到访问者链中)。然后,当您需要一个新变量时,可以调用LocalVariablesSorter.newLocal()方法来获取新的变量槽。有关详细信息,另请参阅ASM guide

答案 1 :(得分:1)

我会查看局部变量调试表,我会使用下一个可用的id,它更可能是2或10而不是3160.

如果您没有调试信息,可能需要多次扫描代码,首先要查看已使用的ID数。

注意:由于历史原因,doublelong需要两个ID。

答案 2 :(得分:1)

newLocal(Type.type)是我发现在我的情况下会有所帮助,谢谢你Eugene Kuleshov和

Peter Lawrey帮忙:)