Author: David Schneider <david.schnei...@picle.org> Branch: Changeset: r64940:fcd5bdf14412 Date: 2013-06-19 13:10 -0500 http://bitbucket.org/pypy/pypy/changeset/fcd5bdf14412/
Log: fix for the bitmask calculation of bitfields in _rawffi and ctypes On 32 bit systems longlong bitfields need a bitmask that is larger than a word diff --git a/pypy/module/_rawffi/structure.py b/pypy/module/_rawffi/structure.py --- a/pypy/module/_rawffi/structure.py +++ b/pypy/module/_rawffi/structure.py @@ -15,7 +15,8 @@ from pypy.module._rawffi.interp_rawffi import size_alignment, LL_TYPEMAP from pypy.module._rawffi.interp_rawffi import unroll_letters_for_numbers from rpython.rlib import clibffi -from rpython.rlib.rarithmetic import intmask, r_uint, signedtype, widen +from rpython.rlib.rarithmetic import intmask, signedtype, widen +from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong def unpack_fields(space, w_fields): fields_w = space.unpackiterable(w_fields) @@ -260,10 +261,17 @@ def LOW_BIT(x): return x & 0xFFFF + def NUM_BITS(x): return x >> 16 -def BIT_MASK(x): - return (1 << x) - 1 + +def BIT_MASK(x, ll_t): + if ll_t is lltype.SignedLongLong: + return (r_longlong(1) << x) - 1 + elif ll_t is lltype.UnsignedLongLong: + return (r_ulonglong(1) << x) - 1 + return (1 << x) -1 +BIT_MASK._annspecialcase_ = 'specialize:arg(1)' def push_field(self, num, value): ptr = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[num]) @@ -279,8 +287,9 @@ lowbit = LOW_BIT(bitsize) if numbits: value = widen(value) + bitmask = BIT_MASK(numbits, TP) + # current = widen(rffi.cast(T, ptr)[0]) - bitmask = BIT_MASK(numbits) current &= ~ (bitmask << lowbit) current |= (value & bitmask) << lowbit value = rffi.cast(TP, current) @@ -301,13 +310,16 @@ numbits = NUM_BITS(bitsize) lowbit = LOW_BIT(bitsize) if numbits: - value = widen(value) + value = widen(rffi.cast(ll_t, value)) + bitmask = BIT_MASK(numbits, ll_t) + # value >>= lowbit - value &= BIT_MASK(numbits) + value &= bitmask if ll_t is lltype.Bool or signedtype(ll_t._type): sign = (value >> (numbits - 1)) & 1 if sign: - value = value - (1 << numbits) + one = r_longlong(1) if ll_t is lltype.SignedLongLong else 1 + value = value - (one << numbits) value = rffi.cast(ll_t, value) break _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit