Accessing local variables in the ASM Java library

天大地大妈咪最大 提交于 2019-12-08 02:53:53

问题


I'm trying to invoke a local variable when inserting a method. Thus far, I'm able to get the local variable in a Node but am having trouble actually accessing anything.

Here is my insertion stuff (it's very scrappy, I've been at this for a while and design stopped being my main priority some time ago):

        final ClassReader reader = new ClassReader("revel/reflection/test/SomeClass");
    final ClassNode classNode = new ClassNode();
    reader.accept(classNode, 0);
    for(final MethodNode mn : (List<MethodNode>)classNode.methods) {
        if(mn.name.equalsIgnoreCase("testLocals")) {
            final InsnList list = new InsnList();

            for(final LocalVariableNode local : (List<LocalVariableNode>)mn.localVariables) {
                System.out.println("Local Variable: " + local.name + " : " + local.desc + " : " + local.signature + " : " + local.index);
                if(local.desc.contains("String")) {
                    mn.visitVarInsn(Opcodes.ALOAD, local.index);
                    final VarInsnNode node = new VarInsnNode(Opcodes.ALOAD, 1);

                    list.add(node);
                    System.out.println("added local var '" + local.name + "'");
                }
            }

            final MethodInsnNode insertion = new MethodInsnNode(Opcodes.INVOKESTATIC, "revel/reflection/test/Test", "printLocalString", "(Ljava/lang/String;)V");
            list.add(insertion);
            mn.instructions.insert(list);
        }
    }

    ClassWriter writer = new ClassWriter(0);
    classNode.accept(writer);

    loadClass(writer.toByteArray(), "revel.reflection.test.SomeClass");
    SomeClass.testLocals(true);

the method it's trying to get into:

    public static void testLocals(boolean one) {
    String two = "hello local variables";
    one = true;
    int three = 64;
}

And it produces:

Local Variable: one : Z : null : 0
Local Variable: two : Ljava/lang/String; : null : 1
added local var 'two'
Local Variable: three : I : null : 2
Exception in thread "main" java.lang.VerifyError: Bad local variable type
Exception Details:
  Location:
    revel/reflection/test/SomeClass.testLocals(Z)V @0: aload_1
  Reason:
    Type top (current frame, locals[1]) is not assignable to reference type
  Current Frame:
    bci: @0
    flags: { }
    locals: { integer }
    stack: { }
  Bytecode:
    0000000: 2bb8 0040 1242 4c04 3b10 403d b12b     

        at revel.reflection.test.Test.main(Test.java:66)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at                         sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Line 66 is SomeClass.testLocals(true); Can anyone shed any light on the situation?


回答1:


It looks like your problem is with the line mn.instructions.insert(list); which is inserting the new instruction at the beginning of the list of all instructions for the method testLocals. In other words, you've put your use of the variable two before it is even declared or assigned a value. Try using mn.instructions.add(list); and see if that doesn't fix things.

Good luck!



来源:https://stackoverflow.com/questions/21807016/accessing-local-variables-in-the-asm-java-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!