Author: Armin Rigo <[email protected]>
Branch: ffi-backend
Changeset: r56485:2775b12955ba
Date: 2012-07-26 22:33 +0200
http://bitbucket.org/pypy/pypy/changeset/2775b12955ba/
Log: Port the first part of the big-endian fix
diff --git a/pypy/module/_cffi_backend/ctypefunc.py
b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -2,6 +2,7 @@
Function pointers.
"""
+import sys
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.rlib import jit, clibffi
@@ -98,7 +99,7 @@
cif_descr = self.cif_descr
size = cif_descr.exchange_size
- mustfree_count_plus_1 = 0
+ mustfree_max_plus_1 = 0
buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
try:
buffer_array = rffi.cast(rffi.VOIDPP, buffer)
@@ -120,7 +121,7 @@
rffi.cast(rffi.CCHARPP, data)[0] = raw_string
# set the "must free" flag to 1
set_mustfree_flag(data, 1)
- mustfree_count_plus_1 = i + 1
+ mustfree_max_plus_1 = i + 1
continue # skip the convert_from_object()
# set the "must free" flag to 0
@@ -148,14 +149,24 @@
buffer_array)
cerrno.save_errno()
- if isinstance(self.ctitem, W_CTypeVoid):
+ if self.ctitem.is_primitive_integer:
+ if BIG_ENDIAN:
+ # For results of precisely these types, libffi has a
+ # strange rule that they will be returned as a whole
+ # 'ffi_arg' if they are smaller. The difference
+ # only matters on big-endian.
+ if self.ctitem.size < SIZE_OF_FFI_ARG:
+ diff = SIZE_OF_FFI_ARG - self.ctitem.size
+ resultdata = rffi.ptradd(resultdata, diff)
+ w_res = self.ctitem.convert_to_object(resultdata)
+ elif isinstance(self.ctitem, W_CTypeVoid):
w_res = space.w_None
elif isinstance(self.ctitem, W_CTypeStructOrUnion):
w_res = self.ctitem.copy_and_convert_to_object(resultdata)
else:
w_res = self.ctitem.convert_to_object(resultdata)
finally:
- for i in range(mustfree_count_plus_1):
+ for i in range(mustfree_max_plus_1):
argtype = self.fargs[i]
if argtype.is_char_ptr_or_array:
data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
@@ -203,7 +214,8 @@
FFI_TYPE = clibffi.FFI_TYPE_P.TO
FFI_TYPE_P = clibffi.FFI_TYPE_P
FFI_TYPE_PP = clibffi.FFI_TYPE_PP
-SIZE_OF_FFI_ARG = 8 # good enough
+SIZE_OF_FFI_ARG = rffi.sizeof(clibffi.ffi_arg)
+BIG_ENDIAN = sys.byteorder == 'big'
CIF_DESCRIPTION = lltype.Struct(
'CIF_DESCRIPTION',
@@ -355,7 +367,7 @@
cif_descr.exchange_result = exchange_offset
# then enough room for the result --- which means at least
- # sizeof(ffi_arg), according to the ffi docs (this is 8).
+ # sizeof(ffi_arg), according to the ffi docs
exchange_offset += max(rffi.getintfield(self.rtype, 'c_size'),
SIZE_OF_FFI_ARG)
diff --git a/pypy/module/_cffi_backend/ctypeobj.py
b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -14,6 +14,7 @@
cast_anything = False
is_char_ptr_or_array = False
is_unichar_ptr_or_array = False
+ is_primitive_integer = False
def __init__(self, space, size, name, name_position):
self.space = space
diff --git a/pypy/module/_cffi_backend/ctypeprim.py
b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -70,7 +70,7 @@
class W_CTypePrimitiveCharOrUniChar(W_CTypePrimitive):
- pass
+ is_primitive_integer = True
class W_CTypePrimitiveChar(W_CTypePrimitiveCharOrUniChar):
@@ -138,6 +138,7 @@
class W_CTypePrimitiveSigned(W_CTypePrimitive):
+ is_primitive_integer = True
def __init__(self, *args):
W_CTypePrimitive.__init__(self, *args)
@@ -173,6 +174,7 @@
class W_CTypePrimitiveUnsigned(W_CTypePrimitive):
+ is_primitive_integer = True
def __init__(self, *args):
W_CTypePrimitive.__init__(self, *args)
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -157,6 +157,7 @@
size_t = rffi_platform.SimpleType("size_t", rffi.ULONG)
ffi_abi = rffi_platform.SimpleType("ffi_abi", rffi.USHORT)
+ ffi_arg = rffi_platform.SimpleType("ffi_arg", lltype.Signed)
ffi_type = rffi_platform.Struct('ffi_type', [('size', rffi.ULONG),
('alignment', rffi.USHORT),
@@ -202,6 +203,7 @@
FFI_TYPE_P.TO.become(cConfig.ffi_type)
size_t = cConfig.size_t
ffi_abi = cConfig.ffi_abi
+ffi_arg = cConfig.ffi_arg
for name in type_names:
locals()[name] = configure_simple_type(name)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit