Author: Armin Rigo <ar...@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, _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit