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
의 잘못된 최적화입니까? 아니면 어떻게 든 그것을 오용하고있는 것입니까?
여기에서 물어 보는 것이 쉽습니다. :)하지만 최소한의 테스트 사례를 추출하려고합니다. – Patrick