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 예제