Author: Armin Rigo <[email protected]>
Branch:
Changeset: r76078:8e51496c7822
Date: 2015-02-23 14:37 +0100
http://bitbucket.org/pypy/pypy/changeset/8e51496c7822/
Log: Raaaah I hate libffi.
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
@@ -564,6 +564,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)))
@@ -594,8 +595,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):
@@ -693,3 +694,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,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit