[pypy-commit] pypy stmgc-c7: Raaaah I hate libffi.

arigo noreply at buildbot.pypy.org
Mon Feb 23 14:42:07 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r76079:5c6438dc2ec7
Date: 2015-02-23 14:37 +0100
http://bitbucket.org/pypy/pypy/changeset/5c6438dc2ec7/

Log:	Raaaah I hate libffi. (grafted from
	8e51496c782298ffe274ce4e64aa33d98be65c0b)

diff --git a/pypy/module/_rawffi/array.py b/pypy/module/_rawffi/array.py
--- a/pypy/module/_rawffi/array.py
+++ b/pypy/module/_rawffi/array.py
@@ -15,7 +15,7 @@
 from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length
 from pypy.module._rawffi.interp_rawffi import read_ptr, write_ptr
 from rpython.rlib.rarithmetic import r_uint
-from rpython.rlib import rgc
+from rpython.rlib import rgc, clibffi
 
 
 class W_Array(W_DataShape):
@@ -84,14 +84,11 @@
 
 class W_ArrayInstance(W_DataInstance):
     def __init__(self, space, shape, length, address=r_uint(0)):
-        # Workaround for a strange behavior of libffi: make sure that
-        # we always have at least 8 bytes.  For W_ArrayInstances that are
-        # used as the result value of a function call, ffi_call() writes
-        # 8 bytes into it even if the function's result type asks for less.
-        # This strange behavior is documented.
         memsize = shape.size * length
-        if memsize < 8:
-            memsize = 8
+        # For W_ArrayInstances that are used as the result value of a
+        # function call, ffi_call() writes 8 bytes into it even if the
+        # function's result type asks for less.
+        memsize = clibffi.adjust_return_size(memsize)
         W_DataInstance.__init__(self, space, memsize, address)
         self.length = length
         self.shape = shape
diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py
--- a/pypy/module/_rawffi/interp_rawffi.py
+++ b/pypy/module/_rawffi/interp_rawffi.py
@@ -495,6 +495,7 @@
         try:
             if self.resshape is not None:
                 result = self.resshape.allocate(space, 1, autofree=True)
+                # adjust_return_size() was used here on result.ll_buffer
                 self.ptr.call(args_ll, result.ll_buffer)
                 return space.wrap(result)
             else:
diff --git a/rpython/rlib/clibffi.py b/rpython/rlib/clibffi.py
--- a/rpython/rlib/clibffi.py
+++ b/rpython/rlib/clibffi.py
@@ -563,6 +563,7 @@
         self.funcsym = funcsym
 
     def call(self, args_ll, ll_result):
+        # adjust_return_size() should always be used here on ll_result
         assert len(args_ll) == len(self.argtypes), (
             "wrong number of arguments in call to %s(): "
             "%d instead of %d" % (self.name, len(args_ll), len(self.argtypes)))
@@ -593,8 +594,8 @@
                                             intmask(argtypes[i].c_size),
                                             flavor='raw')
         if restype != ffi_type_void:
-            self.ll_result = lltype.malloc(rffi.VOIDP.TO,
-                                           intmask(restype.c_size),
+            size = adjust_return_size(intmask(restype.c_size))
+            self.ll_result = lltype.malloc(rffi.VOIDP.TO, size,
                                            flavor='raw')
 
     def push_arg(self, value):
@@ -692,3 +693,12 @@
             dlclose(self.lib)
             self.lib = rffi.cast(DLLHANDLE, -1)
 
+
+def adjust_return_size(memsize):
+    # Workaround for a strange behavior of libffi: make sure that
+    # we always have at least 8 bytes.  ffi_call() writes 8 bytes
+    # into the buffer even if the function's result type asks for
+    # less.  This strange behavior is documented.
+    if memsize < 8:
+        memsize = 8
+    return memsize
diff --git a/rpython/rlib/libffi.py b/rpython/rlib/libffi.py
--- a/rpython/rlib/libffi.py
+++ b/rpython/rlib/libffi.py
@@ -9,7 +9,8 @@
 from rpython.rlib import jit
 from rpython.rlib import clibffi
 from rpython.rlib.clibffi import FUNCFLAG_CDECL, FUNCFLAG_STDCALL, \
-        AbstractFuncPtr, push_arg_as_ffiptr, c_ffi_call, FFI_TYPE_STRUCT
+        AbstractFuncPtr, push_arg_as_ffiptr, c_ffi_call, FFI_TYPE_STRUCT, \
+        adjust_return_size
 from rpython.rlib.rdynload import dlopen, dlclose, dlsym, dlsym_byordinal
 from rpython.rlib.rdynload import DLLHANDLE
 
@@ -369,8 +370,8 @@
         # XXX: check len(args)?
         ll_result = lltype.nullptr(rffi.CCHARP.TO)
         if self.restype != types.void:
-            ll_result = lltype.malloc(rffi.CCHARP.TO,
-                                      intmask(self.restype.c_size),
+            size = adjust_return_size(intmask(self.restype.c_size))
+            ll_result = lltype.malloc(rffi.CCHARP.TO, size,
                                       flavor='raw')
         ffires = c_ffi_call(self.ll_cif,
                             self.funcsym,


More information about the pypy-commit mailing list