2013-01-24 4 views
0

try/finally 블록에서 ASM을 사용하여 메서드를 래핑하려고합니다. 특히 org.objectweb.asm.commons.AdviceAdapter을 확장하고 "3.2.3 메소드 종료 전에 코드 삽입"에서 "Using ASM framework to implement common bytecode transformation patterns"에 설명 된 기술을 확장합니다.org.objectweb.asm.commons.LocalVariablesSorter가 잘못 최적화 되었습니까?

또한 LocalVariablesSorter (수퍼 클래스는 AdviceAdapter)을 사용하여 finally 블록에서 사용하는 메소드 시작 부분에 로컬 변수를 추가 할 수 있습니다.

나는 ASM으로 수정하려고 시도하고있는 방법이있다. 방법은 세 가지 인수를 받아 자신의 어떤 지역 주민들이 없습니다 : 내 finally 블록은 예외 핸들러의 대상이 될 수 있기 때문에

class Example { 
    public static int f4(int i, long l, int f) { 
     return (int) (i + l + f); 
    } 
} 

, 나는 메소드 매개 변수를 전달, 전화 그래서 super.visitFrame(F_NEW, ...)를 추가합니다. 이 클래스가 수퍼 클래스를 호출하기 때문에 newLocal이 LocalVariablesSorter에 의해이 프레임에 추가 될 것으로 예상됩니다. 그러나 이것을 ASM 파이프 라인을 통해 실행할 때 Java 7은 오류 java.lang.VerifyError: Bad local variable type in method Example.f4(IJI)I at offset 32을 제공합니다.

visitFrame 방법, 나는 그것이 부울 changed을 가지고 있으며, 변경하지 않을 경우 visitFrame 내가 만든 될 수있는 새로운 지역 주민의 대가를 건너 뜁니다 것을 참조 source of LocalVariablesSorter에서 찾고있다. 이 changed 부울은 새 로컬 생성을 위해 LocalVariablesSorter을 사용하기 때문에 업스트림 바이트 코드가 다시 매핑되어야하는 변수에 대해 특정 작업을 수행 할 때만 설정되는 것처럼 보입니다 (위의 f4() 메서드에서는 이러한 작업이 발생하지 않습니다). 이 해결 방법을 적용하여

는 :

 Field field = LocalVariablesSorter.class.getDeclaredField("changed"); 
     field.setAccessible(true); 
     field.setBoolean(this, true); 

나는 자바 7의 검증을 통과 할 수 있어요.

전에 :

내 반사 후
FRAME FULL [I J I] [java/lang/Throwable] 

(나는 추가하고 새로운 지역을 해킹 또한, TraceClassVisitor ASM 유틸리티를 사용하여, 난 그냥 마지막 블록의 시작 전에 스택지도 프레임의 차이를 볼 는 int입니다.) :

FRAME FULL [I J I I] [java/lang/Throwable] 

주변 코드는 공유하지 않았지만 제 질문은 일반적인 것입니다. 이 changed 부울 값이 LocalVariablesSorter의 잘못된 최적화입니까? 아니면 어떻게 든 그것을 오용하고있는 것입니까?

답변

0

LocalVariablesSorter.visitFrame(..) 호출은 지역을 추가하지 않으며 추가 프레임에 대한 정보 만 기록하도록 ASM에 알립니다. LocalVariablesSorter.newLocal(..)으로 전화하여 지역 주민을 추가해야합니다.

일반적으로 ASM에서 버그를 발견했다면 버그 보고서를 ASM issue tracker에게 제출하고 문제를 재현 할 수있는 테스트 코드 (예 : 테스트 클래스 및 전체 변형)를 제공하는 것이 좋습니다.

+0

여기에서 물어 보는 것이 쉽습니다. :)하지만 최소한의 테스트 사례를 추출하려고합니다. – Patrick