[pypy-commit] pypy ffi-backend: Progress...
arigo
noreply at buildbot.pypy.org
Wed Jun 20 12:29:12 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r55727:b46e2561f838
Date: 2012-06-19 21:59 +0200
http://bitbucket.org/pypy/pypy/changeset/b46e2561f838/
Log: Progress...
diff --git a/pypy/module/_ffi_backend/cdataobj.py b/pypy/module/_ffi_backend/cdataobj.py
--- a/pypy/module/_ffi_backend/cdataobj.py
+++ b/pypy/module/_ffi_backend/cdataobj.py
@@ -3,9 +3,11 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.objectmodel import keepalive_until_here
from pypy.rlib import rgc
+from pypy.module._ffi_backend import misc
+
class W_CData(Wrappable):
_immutable_ = True
@@ -22,20 +24,22 @@
def repr(self):
return self.space.wrap("<cdata '%s'>" % self.ctype.name)
+ def int(self):
+ return self.ctype.int(self)
+
+ def read_raw_signed_data(self):
+ result = misc.read_raw_signed_data(self.cdata, self.ctype.size)
+ keepalive_until_here(self)
+ return result
+
+ def read_raw_unsigned_data(self):
+ result = misc.read_raw_unsigned_data(self.cdata, self.ctype.size)
+ keepalive_until_here(self)
+ return result
+
def write_raw_integer_data(self, source):
- size = self.ctype.size
- for TP, TPP in _prim_unsigned_types:
- if size == rffi.sizeof(TP):
- rffi.cast(TPP, self.cdata)[0] = rffi.cast(TP, source)
- return
- raise NotImplementedError("bad integer size")
-
-_prim_unsigned_types = unrolling_iterable([
- (rffi.UCHAR, rffi.UCHARP),
- (rffi.USHORT, rffi.USHORTP),
- (rffi.UINT, rffi.UINTP),
- (rffi.ULONG, rffi.ULONGP),
- (rffi.ULONGLONG, rffi.ULONGLONGP)])
+ misc.write_raw_integer_data(self.cdata, source, self.ctype.size)
+ keepalive_until_here(self)
class W_CDataOwn(W_CData):
@@ -52,6 +56,7 @@
W_CData.typedef = TypeDef(
'_ffi_backend.CData',
__repr__ = interp2app(W_CData.repr),
+ __int__ = interp2app(W_CData.int),
)
W_CData.acceptable_as_base_class = False
diff --git a/pypy/module/_ffi_backend/ctypeobj.py b/pypy/module/_ffi_backend/ctypeobj.py
--- a/pypy/module/_ffi_backend/ctypeobj.py
+++ b/pypy/module/_ffi_backend/ctypeobj.py
@@ -3,6 +3,7 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rlib.rarithmetic import intmask
from pypy.module._ffi_backend import cdataobj, misc
@@ -22,6 +23,11 @@
def cast(self, w_ob):
raise NotImplementedError
+ def int(self, cdataobj):
+ space = self.space
+ raise operationerrfmt(space.w_TypeError,
+ "int() not supported on cdata '%s'", self.name)
+
class W_CTypePrimitive(W_CType):
@@ -41,11 +47,27 @@
class W_CTypePrimitiveChar(W_CTypePrimitive):
- pass
+
+ def int(self, cdataobj):
+ xxx
+
class W_CTypePrimitiveSigned(W_CTypePrimitive):
- pass
+ def int(self, cdataobj):
+ if self.value_fits_long:
+ # this case is to handle enums, but also serves as a slight
+ # performance improvement for some other primitive types
+ value = intmask(cdataobj.read_raw_signed_data())
+ return self.space.wrap(value)
+ else:
+ return cdataobj.convert_to_object()
+
+
+class W_CTypePrimitiveUnsigned(W_CTypePrimitive):
+
+ def int(self, cdataobj):
+ return cdataobj.convert_to_object()
W_CType.typedef = TypeDef(
diff --git a/pypy/module/_ffi_backend/misc.py b/pypy/module/_ffi_backend/misc.py
--- a/pypy/module/_ffi_backend/misc.py
+++ b/pypy/module/_ffi_backend/misc.py
@@ -1,5 +1,43 @@
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rlib.rarithmetic import r_ulonglong
+from pypy.rlib.unroll import unrolling_iterable
+
+# ____________________________________________________________
+
+_prim_signed_types = unrolling_iterable([
+ (rffi.SIGNEDCHAR, rffi.SIGNEDCHARP),
+ (rffi.SHORT, rffi.SHORTP),
+ (rffi.INT, rffi.INTP),
+ (rffi.LONG, rffi.LONGP),
+ (rffi.LONGLONG, rffi.LONGLONGP)])
+
+_prim_unsigned_types = unrolling_iterable([
+ (rffi.UCHAR, rffi.UCHARP),
+ (rffi.USHORT, rffi.USHORTP),
+ (rffi.UINT, rffi.UINTP),
+ (rffi.ULONG, rffi.ULONGP),
+ (rffi.ULONGLONG, rffi.ULONGLONGP)])
+
+def read_raw_signed_data(target, size):
+ for TP, TPP in _prim_signed_types:
+ if size == rffi.sizeof(TP):
+ return rffi.cast(rffi.LONGLONG, rffi.cast(TPP, target)[0])
+ raise NotImplementedError("bad integer size")
+
+def read_raw_unsigned_data(target, size):
+ for TP, TPP in _prim_unsigned_types:
+ if size == rffi.sizeof(TP):
+ return rffi.cast(rffi.ULONGLONG, rffi.cast(TPP, target)[0])
+ raise NotImplementedError("bad integer size")
+
+def write_raw_integer_data(target, source, size):
+ for TP, TPP in _prim_unsigned_types:
+ if size == rffi.sizeof(TP):
+ rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+ return
+ raise NotImplementedError("bad integer size")
+
+# ____________________________________________________________
UNSIGNED = 0x1000
diff --git a/pypy/module/_ffi_backend/newtype.py b/pypy/module/_ffi_backend/newtype.py
--- a/pypy/module/_ffi_backend/newtype.py
+++ b/pypy/module/_ffi_backend/newtype.py
@@ -11,16 +11,27 @@
PRIMITIVE_TYPES = {}
def eptype(name, TYPE, ctypecls):
- PRIMITIVE_TYPES[name] = ctypecls, rffi.sizeof(TYPE)
+ size = rffi.sizeof(TYPE)
+ if ctypecls is ctypeobj.W_CTypePrimitiveSigned:
+ value_fits_long = size <= rffi.sizeof(lltype.Signed)
+ elif ctypecls is ctypeobj.W_CTypePrimitiveUnsigned:
+ value_fits_long = size < rffi.sizeof(lltype.Signed)
+ else:
+ value_fits_long = False
+ PRIMITIVE_TYPES[name] = ctypecls, size, value_fits_long
-eptype("char", lltype.Char, ctypeobj.W_CTypePrimitiveChar)
+eptype("char", lltype.Char, ctypeobj.W_CTypePrimitiveChar)
eptype("signed char", rffi.SIGNEDCHAR, ctypeobj.W_CTypePrimitiveSigned)
+eptype("short", rffi.SHORT, ctypeobj.W_CTypePrimitiveSigned)
+# xxx
@unwrap_spec(name=str)
def new_primitive_type(space, name):
try:
- ctypecls, size = PRIMITIVE_TYPES[name]
+ ctypecls, size, value_fits_long = PRIMITIVE_TYPES[name]
except KeyError:
raise OperationError(space.w_KeyError, space.wrap(name))
- return ctypecls(space, name, size)
+ ctype = ctypecls(space, name, size)
+ ctype.value_fits_long = value_fits_long
+ return ctype
More information about the pypy-commit
mailing list