[pypy-commit] pypy default: reintroduce changes done in b6390a34f261 to push_arg_as_ffiptr in clibffi.py, somehow lost in a731ffd298b4
bivab
noreply at buildbot.pypy.org
Tue Jan 10 14:11:31 CET 2012
Author: David Schneider <david.schneider at picle.org>
Branch:
Changeset: r51202:e2f82a5d9f5e
Date: 2012-01-10 14:09 +0100
http://bitbucket.org/pypy/pypy/changeset/e2f82a5d9f5e/
Log: reintroduce changes done in b6390a34f261 to push_arg_as_ffiptr in
clibffi.py, somehow lost in a731ffd298b4
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -30,6 +30,9 @@
_MAC_OS = platform.name == "darwin"
_FREEBSD_7 = platform.name == "freebsd7"
+_LITTLE_ENDIAN = sys.byteorder == 'little'
+_BIG_ENDIAN = sys.byteorder == 'big'
+
if _WIN32:
from pypy.rlib import rwin32
@@ -360,12 +363,36 @@
cast_type_to_ffitype._annspecialcase_ = 'specialize:memo'
def push_arg_as_ffiptr(ffitp, arg, ll_buf):
- # this is for primitive types. For structures and arrays
- # would be something different (more dynamic)
+ # This is for primitive types. Note that the exact type of 'arg' may be
+ # different from the expected 'c_size'. To cope with that, we fall back
+ # to a byte-by-byte copy.
TP = lltype.typeOf(arg)
TP_P = lltype.Ptr(rffi.CArray(TP))
- buf = rffi.cast(TP_P, ll_buf)
- buf[0] = arg
+ TP_size = rffi.sizeof(TP)
+ c_size = intmask(ffitp.c_size)
+ # if both types have the same size, we can directly write the
+ # value to the buffer
+ if c_size == TP_size:
+ buf = rffi.cast(TP_P, ll_buf)
+ buf[0] = arg
+ else:
+ # needs byte-by-byte copying. Make sure 'arg' is an integer type.
+ # Note that this won't work for rffi.FLOAT/rffi.DOUBLE.
+ assert TP is not rffi.FLOAT and TP is not rffi.DOUBLE
+ if TP_size <= rffi.sizeof(lltype.Signed):
+ arg = rffi.cast(lltype.Unsigned, arg)
+ else:
+ arg = rffi.cast(lltype.UnsignedLongLong, arg)
+ if _LITTLE_ENDIAN:
+ for i in range(c_size):
+ ll_buf[i] = chr(arg & 0xFF)
+ arg >>= 8
+ elif _BIG_ENDIAN:
+ for i in range(c_size-1, -1, -1):
+ ll_buf[i] = chr(arg & 0xFF)
+ arg >>= 8
+ else:
+ raise AssertionError
push_arg_as_ffiptr._annspecialcase_ = 'specialize:argtype(1)'
More information about the pypy-commit
mailing list