rpython 언어의 가능한 개선 사항 =============================== 인터프리터 API 개선 ------------------- - PyPy 모듈을 구현하는 데 필요한 다양한 함수들의 모듈과 이름을 합리화합니다. 일반적인 RPython 파일에는 `import`\ 문이 많이 포함되어 있을 수 있습니다.:: from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.gateway import ObjSpace, W_Root from pypy.interpreter.argument import Arguments from pypy.interpreter.typedef import TypeDef, GetSetProperty from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app from pypy.interpreter.error import OperationError from rpython.rtyper.lltypesystem import rffi, lltype - Typedef를 작성하는 더 직접적인 선언적 방법:: class W_Socket(W_Root): _typedef_name_ = 'socket' _typedef_base_ = W_EventualBaseClass @interp2app_method("connect", ['self', ObjSpace, W_Root]) def connect_w(self, space, w_addr): ... - RPython으로 작성된 메타클래스를 지원합니다. 예시로는 건너뛴(skipped) 테스트인 `pypy.objspace.std.test.TestTypeObject.test_metaclass_typedef`\ 를 참고하십시오. RPython 언어 ------------ - 부호 없는 정수를 사용한 산술 연산, 그리고 모호하지 않은 경우 부호가 다른 정수 간의 산술 연산. 최소한, 상수와의 비교 및 할당은 허용되어야 합니다. - 변수를 스택에 할당하고, 그 주소를("참조로") llexternal 함수에 전달합니다. 일반적인 사용법은 `rpython.rlib.rsocket.RSocket.getsockopt_int`\ 를 참조하십시오. llexternal을 위한 확장 가능한 타입 시스템 ----------------------------------------- llexternal은 C 함수의 설명을 가능하게 하며, C 헤더와 동일한 인자 정보를 전달합니다. 하지만 이것으로는 종종 충분하지 않습니다. 예를 들어, `int*` 타입의 매개변수는 `rffi.CArrayPtr(rffi.INT)`\ 로 변환되지만, 이 정보만으로는 함수를 사용하기에 충분하지 않습니다. 해당 매개변수는 int 배열일 수도, 입력 또는 출력을 위한 단일 값에 대한 참조일 수도 있습니다... "타입 시스템"은 이 추가 정보를 보유하고, RPython에서 함수 사용을 쉽게 만들기 위해 변환 코드를 자동으로 생성할 수 있습니다. 예를 들어:: # double frexp(double x, int *exp); frexp = llexternal("frexp", [rffi.DOUBLE, OutPtr(rffi.int)], rffi.DOUBLE) `OutPtr`\ 는 매개변수가 출력 전용임을 나타내며, 초기화할 필요가 없고, 그 *값*\ 이 호출자에게 반환됩니다. RPython에서는 그 호출이 다음과 같이 됩니다:: fraction, exponent = frexp(value) 또한, llexternal 인자 목록의 한 항목이 C의 두 매개변수에 대응하는 경우도 생각해볼 수 있습니다. 여기서 OutCharBufferN은 호출자가 RPython 문자열을 전달함을 나타내며, 프레임워크가 함수에 버퍼와 길이를 전달합니다.:: # ssize_t write(int fd, const void *buf, size_t count); write = llexternal("write", [rffi.INT, CharBufferAndSize], rffi.SSIZE_T) 이 함수를 호출하는 rpython 코드는 매우 간단합니다:: written = write(fd, data) 현재와 비교하여:: count = len(data) buf = rffi.get_nonmovingbuffer(data) try: written = rffi.cast(lltype.Signed, os_write( rffi.cast(rffi.INT, fd), buf, rffi.cast(rffi.SIZE_T, count))) finally: rffi.free_nonmovingbuffer(data, buf) 타입맵(typemap)은 동일한 변환이 여러 곳에서 필요한 대규모 API에서 매우 유용합니다. XXX 예제