[pypy-commit] pypy ppc-jit-backend: Tentatively rewrite push_arg_as_ffiptr().
arigo
noreply at buildbot.pypy.org
Fri Nov 11 09:22:02 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: ppc-jit-backend
Changeset: r49294:066646be3787
Date: 2011-11-10 18:14 +0100
http://bitbucket.org/pypy/pypy/changeset/066646be3787/
Log: Tentatively rewrite push_arg_as_ffiptr().
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -340,46 +340,38 @@
return TYPE_MAP[tp]
cast_type_to_ffitype._annspecialcase_ = 'specialize:memo'
-def push_arg_as_ffiptr_base(ffitp, arg, ll_buf):
- # this is for primitive types. For structures and arrays
- # would be something different (more dynamic)
- # XXX is this valid in C?, for args that are larger than the size of
- # ll_buf we write over the boundaries of the allocated char array and
- # just keep as much bytes as we need for the target type. Maybe using
- # memcpy would be better here. Also this
- # only works on little endian architectures
- TP = lltype.typeOf(arg)
- TP_P = lltype.Ptr(rffi.CArray(TP))
- buf = rffi.cast(TP_P, ll_buf)
- buf[0] = arg
-push_arg_as_ffiptr_base._annspecialcase_ = 'specialize:argtype(1)'
-
-def push_arg_as_ffiptr_memcpy(ffitp, arg, ll_buf):
- # this is for primitive types. For structures and arrays
- # would be something different (more dynamic)
+def push_arg_as_ffiptr(ffitp, arg, ll_buf):
+ # 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))
TP_size = rffi.sizeof(TP)
c_size = intmask(ffitp.c_size)
-
- # if both types have the same size, we do not can directly write the
+ # if both types have the same size, we can directly write the
# value to the buffer
if c_size == TP_size:
- return push_arg_as_ffiptr_base(ffitp, arg, ll_buf)
-
- # store arg in a small box in memory
- # and copy the relevant bytes over to the target buffer (ll_buf)
- with lltype.scoped_alloc(TP_P.TO, TP_size) as argbuf:
- argbuf[0] = arg
- cargbuf = rffi.cast(rffi.CCHARP, argbuf)
- ptr = rffi.ptradd(cargbuf, TP_size - c_size)
- rffi.c_memcpy(ll_buf, ptr, c_size)
-push_arg_as_ffiptr_memcpy._annspecialcase_ = 'specialize:argtype(1)'
-
-if _LITTLE_ENDIAN:
- push_arg_as_ffiptr = push_arg_as_ffiptr_base
-else:
- push_arg_as_ffiptr = push_arg_as_ffiptr_memcpy
+ 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)'
# type defs for callback and closure userdata
USERDATA_P = lltype.Ptr(lltype.ForwardReference())
More information about the pypy-commit
mailing list