2014-02-16 3 views
2

메소드를 삽입 할 때 로컬 변수를 호출하려고합니다. 지금까지 Node에서 로컬 변수를 가져올 수 있었지만 실제로 아무것도 액세스하는 데 문제가있었습니다.ASM Java 라이브러리에서 로컬 변수에 액세스

 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); 

가 들어갈하려고 방법 : 여기

내 삽입 물건 (그것이 내가이 잠시 동안 매우 단편적인 있었어요 그리고 디자인은 몇 시간 전에 내 주요 우선 순위 인 중지)입니다 :

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

그리고 그것은 생산 :

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) 

라인 (66) SomeClass.testLocals (참)이다; 상황에 대해 밝히는 사람이 있습니까?

답변

1

testLocals 메소드의 모든 명령어 목록 시작 부분에 새 명령어를 삽입하는 행 mn.instructions.insert(list);이 문제가되는 것 같습니다. 즉 변수가 선언되거나 값이 지정되기 전에 변수 two을 사용했습니다. mn.instructions.add(list);을 사용해보고 문제가 해결되지 않는지 확인하십시오.

행운을 빈다.

+0

정확히 그게 문제입니다. 나는 내가 그 생각을하지 않았다는 것을 믿을 수 없다. 감사! – Kieran

관련 문제