목표와 아키텍처 개요¶
이 문서는 PyPy의 목표와 아키텍처에 대한 개요를 제공합니다. PyPy를 사용하거나 이를 해킹하는 데 관심이 있으시다면, 저희 시작하기 섹션을 참고하세요.
미션 선언문¶
저희는 규격을 준수하며 유연하고 빠른 Python언어 구현체를 제공하는 것을 목표로 하며, 이를 위해 저수준 세부 사항을 직접 기술하지 않고도 새롭고 진보된 고수준 기능을 지원할 수 있는 RPython 툴체인을 사용합니다. 저희는 이를 PyPy라고 부릅니다.
상위 수준 목표¶
번역(translation) 프레임워크를 개발하는 주된 동기는, 다양한 플랫폼에서 동작하고 상호작용하며 새로운 고급 언어 기능을 빠르게 도입할 수 있도록 하는, 완전한 기능을 갖추고 커스터마이징 가능하며 빠르고 매우 호환성이 높은 Python 구현을 제공하는 것입니다.
이 Python 구현체는 상대적으로 단순한 인터프리터로서 RPython으로 작성되었으며, 어떤 면에서는 Python의 C 참조 구현체인 CPython보다 이해하기 쉽습니다. 우리는 RPython의 고수준성과 유연성을 활용하여, 전통적인 접근 방식이라면 소스 코드 전반에 걸친 변경이 필요했을 방식으로 기능이나 구현 기법을 빠르게 실험하고 있습니다. 예를 들어, PyPy의 Python 인터프리터는 선택적으로 지연 계산 객체(lazily computed objects)를 제공할 수 있는데, 이는 CPython에서라면 전역적인 변경이 필요했을 작은 확장입니다. 또 다른 예는 가비지 컬렉션 기법입니다. 참조 카운팅에 기반하지 않은 가비지 컬렉터를 사용하도록 CPython을 변경하는 것은 대규모 작업이 되겠지만, PyPy에서는 이것이 번역(translation) 프레임워크 내에 국한된 문제이며 인터프리터 소스 코드와는 완전히 무관합니다.
PyPy Python 인터프리터¶
PyPy의 Python 인터프리터는 RPython으로 작성되었으며, 전체 Python 언어를 구현합니다. 이 인터프리터는 CPython의 동작을 매우 유사하게 모방합니다. 다음과 같은 핵심 구성 요소를 포함합니다:
- 사용자 애플리케이션의 소스 코드로부터 파이썬 코드 객체를 생성하는 역할을 담당하는 바이트코드 컴파일러;
- Python 코드 객체를 해석하는 역할을 담당하는 바이트코드 평가기;
- 애플리케이션이 보는 Python 객체를 생성하고 조작하는 역할을 하는 표준 객체 공간(object space)
바이트코드 컴파일러는 토크나이저(tokenizer), 렉서(lexer), 파서(parser), 추상 구문 트리 빌더(abstract syntax tree builder), 바이트코드 생성기(bytecode generator)로 이어지는 유연한 처리 단계들의 연쇄를 통해 압축된 바이트코드 형식을 생성하는 전처리 단계입니다. 바이트코드 평가기는 이 바이트코드를 해석합니다. 이는 사용자 객체에 대한 실제 조작을 모두 객체 공간(object space)에 위임함으로써 대부분의 작업을 수행합니다. 후자는 내장 타입들의 라이브러리로 생각할 수 있습니다. 이는 정수나 리스트와 같은 사용자 객체의 구현뿐만 아니라, 덧셈이나 진리값 검사와 같은 이들 간의 연산도 정의합니다.
바이트코드 평가기와 객체 공간(object space) 사이의 이러한 구분은 많은 유연성을 제공합니다. 서로 다른 객체 공간(object space)을 끼워 넣어 파이썬 객체의 다르거나 강화된 동작을 얻을 수 있습니다.
계층¶
RPython¶
RPython는 저희가 인터프리터를 작성하는 언어입니다. PyPy 프로젝트 전체가 RPython으로 작성된 것은 아니며, 번역(translation) 과정에서 컴파일되는 부분만 RPython으로 작성됩니다. 흥미로운 점은 RPython에는 파서가 없고, 실행 중인 파이썬 객체로부터 컴파일된다는 것인데, 이 덕분에 임포트 시점에 온갖 종류의 메타프로그래밍이 가능해집니다. 요컨대, 파이썬은 RPython을 위한 메타프로그래밍 언어입니다.
RPython 표준 라이브러리는 rlib 하위 디렉터리에 있습니다.
더 읽을거리를 원하시면 Getting Started with RPython을, 인터프리터를 작성하지 않고도 RPython으로 할 수 있는 일에 대한 또 다른 관점을 보시려면 RPython By Example을 참고하십시오.
번역(translation)¶
번역(translation) 툴체인 - RPython을 흐름 그래프(flow graph)로, 그리고 다시 C로 번역하는 것을 담당하는 부분입니다. 이에 대해서는 architecture문서에 더 자세히 나와 있습니다.
이는 rpython 디렉터리, 즉 flowspace, annotator, rtyper에 있습니다.
PyPy 인터프리터¶
이것은 pypy 디렉터리에 있습니다. pypy/interpreter는 RPython으로 작성된 Python용 표준 인터프리터입니다. 이것이 RPython이라는 사실은 처음에는 명확하지 않습니다. 내장 모듈은 pypy/module/*에 작성되어 있습니다. CPython이 C로 구현하는 일부 모듈은 단순히 순수 Python으로 작성되어 있으며, 최상위 lib_pypy 디렉터리에 있습니다. Python의 표준 라이브러리(PyPy에 맞추기 위한 몇 가지 변경 사항 포함)는 lib-python에 있습니다.
JIT 컴파일러¶
Just-in-Time Compiler (JIT): 우리는 해석 대상인 사용자 프로그램이 아니라 RPython으로 작성된 인터프리터를 트레이싱하는 트레이싱 JIT을 가지고 있습니다. 결과적으로 이는 모든 인터프리터, 즉 모든 언어에 적용됩니다. 하지만 이를 올바르게 동작하게 만드는 것은 간단하지 않습니다: 소수의 정밀한 “힌트”가 필요하며, 경우에 따라 인터프리터에 대한 약간의 리팩터링도 필요합니다. JIT 자체도 거의 독립적인 여러 부분으로 구성되어 있습니다: rpython/jit/metainterp에 있는 트레이서 자체, 잔여 연산 목록을 최적화하는 rpython/jit/metainterp/optimizer의 최적화기, 그리고 이를 기계어 코드로 변환하는 rpython/jit/backend/<machine-name>의 백엔드입니다. 새로운 백엔드를 작성하는 것은 프로젝트에 참여하는 전통적인 방법입니다.
가비지 컬렉터¶
가비지 컬렉터(GC): CPython의 C 코드에 익숙하다면 눈치챌 수 있듯이, RPython 코드에는 Py_INCREF/Py_DECREF에 해당하는 것이 없습니다. Garbage Collection in RPython은 번역(translation) 중에 삽입됩니다. 또한, 이는 참조 카운팅이 아니라 더 많은 RPython 코드로 작성된 실제 GC입니다. 지금까지 가장 좋은 것은 rpython/memory/gc/incminimark.py에 있습니다.