[pypy-commit] pypy release-5.x: _rawffi bigendian issue in callbacks, callback writes narrow integer directly to MSB of 64 bit value on s390x (wrong when value is passed along)
plan_rich
pypy.commits at gmail.com
Sun Mar 27 16:43:19 EDT 2016
Author: Richard Plangger <planrichi at gmail.com>
Branch: release-5.x
Changeset: r83402:3624c8c2c3be
Date: 2016-02-10 18:07 +0100
http://bitbucket.org/pypy/pypy/changeset/3624c8c2c3be/
Log: _rawffi bigendian issue in callbacks, callback writes narrow integer
directly to MSB of 64 bit value on s390x (wrong when value is passed
along) (grafted from 74ebd8669f961c3ba5835f052356a9000298af98)
diff --git a/pypy/module/_rawffi/callback.py b/pypy/module/_rawffi/callback.py
--- a/pypy/module/_rawffi/callback.py
+++ b/pypy/module/_rawffi/callback.py
@@ -1,17 +1,23 @@
-
+import sys
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from rpython.rtyper.lltypesystem import lltype, rffi
from pypy.module._rawffi.interp_rawffi import write_ptr
from pypy.module._rawffi.structure import W_Structure
from pypy.module._rawffi.interp_rawffi import (W_DataInstance, letter2tp,
- unwrap_value, unpack_argshapes, got_libffi_error)
+ unwrap_value, unpack_argshapes, got_libffi_error, is_narrow_integer_type,
+ LL_TYPEMAP, NARROW_INTEGER_TYPES)
from rpython.rlib.clibffi import USERDATA_P, CallbackFuncPtr, FUNCFLAG_CDECL
from rpython.rlib.clibffi import ffi_type_void, LibFFIError
from rpython.rlib import rweakref
from pypy.module._rawffi.tracker import tracker
from pypy.interpreter.error import OperationError
from pypy.interpreter import gateway
+from rpython.rlib.unroll import unrolling_iterable
+
+BIGENDIAN = sys.byteorder == 'big'
+
+unroll_narrow_integer_types = unrolling_iterable(NARROW_INTEGER_TYPES)
app = gateway.applevel('''
def tbprint(tb, err):
@@ -42,8 +48,17 @@
args_w[i] = space.wrap(rffi.cast(rffi.ULONG, ll_args[i]))
w_res = space.call(w_callable, space.newtuple(args_w))
if callback_ptr.result is not None: # don't return void
- unwrap_value(space, write_ptr, ll_res, 0,
- callback_ptr.result, w_res)
+ ptr = ll_res
+ letter = callback_ptr.result
+ if BIGENDIAN:
+ # take care of narrow integers!
+ for int_type in unroll_narrow_integer_types:
+ if int_type == letter:
+ T = LL_TYPEMAP[int_type]
+ n = rffi.sizeof(lltype.Signed) - rffi.sizeof(T)
+ ptr = rffi.ptradd(ptr, n)
+ break
+ unwrap_value(space, write_ptr, ptr, 0, letter, w_res)
except OperationError, e:
tbprint(space, space.wrap(e.get_traceback()),
space.wrap(e.errorstr(space)))
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
@@ -440,6 +440,10 @@
space.wrap("cannot directly read value"))
wrap_value._annspecialcase_ = 'specialize:arg(1)'
+NARROW_INTEGER_TYPES = 'cbhiBIH?'
+
+def is_narrow_integer_type(letter):
+ return letter in NARROW_INTEGER_TYPES
class W_FuncPtr(W_Root):
def __init__(self, space, ptr, argshapes, resshape):
@@ -448,7 +452,7 @@
self.resshape = resshape
self.narrow_integer = False
if resshape is not None:
- self.narrow_integer = resshape.itemcode.lower() in ('c','h','i')
+ self.narrow_integer = is_narrow_integer_type(resshape.itemcode.lower())
def getbuffer(self, space):
return space.wrap(rffi.cast(lltype.Unsigned, self.ptr.funcsym))
@@ -512,7 +516,6 @@
# we get a 8 byte value in big endian
n = rffi.sizeof(lltype.Signed) - result.shape.size
result.buffer_advance(n)
-
return space.wrap(result)
else:
self.ptr.call(args_ll, lltype.nullptr(rffi.VOIDP.TO))
More information about the pypy-commit
mailing list