Rust 컴파일러의 내부 정보를 읽기 쉬운 형식으로 추출하는 프로젝트 Charon이 커널 도구 제작과 Rust 코드 분석에 활용될 수 있다. Kangrejos에서 발표한 Nadrieril은 Charon이 컴파일러 내부 인터페이스 변경을 한곳에서 관리해 도구 개발 부담을 줄이는 것을 목표로 한다고 설명했다.
Rust에는 암묵적으로 처리되는 기능이 많아, 컴파일러가 코드를 어떻게 해석하는지 파악하려면 rustc의 상당 부분을 다시 구현해야 한다. 기존 도구는 rustc 내부 인터페이스를 사용하기도 하지만, 이 인터페이스는 예고 없이 바뀔 수 있고 안정성이 보장되지 않는다. Charon은 rustc가 보는 정보를 안정적인 API로 제공하고, 변경에 대응하는 작업을 한곳에 모으려 한다.
charon cargo를 실행하면 Cargo처럼 Rust 프로젝트를 컴파일하고, 크레이트의 타입·트레이트·함수 정보를 담은 JSON 형식의 .llbc 파일도 출력한다. JSON을 사람이 읽기 쉬운 Rust 유사 문법으로 출력할 수도 있다. 이 표현은 주석과 추가 문장으로 암묵적 동작을 드러내며, 예를 들어 스택 되감기 과정의 제어 흐름은 ⚡ 기호로 표시한다. 값이 해제되는 위치와 변수 타입도 확인할 수 있고, 원본 주석도 보존한다.
Charon은 커널의 C 구조체를 Rust로 변환하는 bindgen의 출력을 분석하는 데도 쓰일 수 있다. 커널의 list_head 구조체 사례에서는 rustc가 선택한 메모리 배치와 컴파일러 버전 사이에 안정적으로 유지된다고 보장되는 배치 정보를 함께 보여준다. 출력에는 구조체에도 단일 변형 정보가 포함되는 등 중복이 있지만, 구조와 열거형, 함수가 일관된 형식을 따르기 때문에 이를 처리하는 도구를 간단히 작성할 수 있다. 발표에서 소개된 std::thread::spawn() 호출을 검사하는 사용자 정의 린터는 약 60줄이다.
Charon은 Rust 코드를 다른 언어로 옮기는 데도 활용된다. Rust 코드에서 생성한 OCaml 바인딩이 있으며, Rust를 C나 Lean으로 변환한 사례도 있다. Rust-to-C 변환은 안전한 Rust만을 대상으로 하며, Nadrieril은 이 범위에서 읽기 쉬운 C 코드를 생성한다고 설명했다. 다만 읽기 쉬운 코드를 만드는 것과 빠른 코드를 만드는 것은 다르다. Nadrieril은 Rust와 C에서 성능이 좋은 코드 패턴이 일치하지 않을 수 있어, Rust에서 빠른 C 코드를 생성하는 일은 더 어렵다고 말했다.
Charon은 기본적으로 MIR을 사용하며, 사용자가 --precise-drops 플래그를 지정하면 일부 최적화가 드롭 위치를 바꿀 수 있는 elaborated MIR을 이용한다. 현재 비동기 코드를 제외한 Rust 기능을 지원하며 버그가 남아 있지만, Nadrieril은 버그가 없는 경우 올바른 출력을 생성한다고 밝혔다. 프로젝트는 1.0 릴리스를 앞두고 있다. 컴파일러가 코드를 해석한 정보를 바탕으로 린터나 변환 도구를 만들려는 개발자는 Charon 프로젝트와 발표 데모 모음을 참고할 수 있다.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요