[pypy-commit] pypy stdlib-2.7.6: fix _rawffi bitfield mask calculation
bdkearns
noreply at buildbot.pypy.org
Sun Mar 2 16:29:48 CET 2014
Author: Brian Kearns <bdkearns at gmail.com>
Branch: stdlib-2.7.6
Changeset: r69614:0bee77fda190
Date: 2014-03-02 09:32 -0500
http://bitbucket.org/pypy/pypy/changeset/0bee77fda190/
Log: fix _rawffi bitfield mask calculation
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
@@ -1,4 +1,3 @@
-
""" Interpreter-level implementation of structure, exposing ll-structure
to app-level with apropriate interface
"""
@@ -17,8 +16,8 @@
from pypy.module._rawffi.interp_rawffi import size_alignment
from pypy.module._rawffi.interp_rawffi import read_ptr, write_ptr
from rpython.rlib import clibffi, rgc
-from rpython.rlib.rarithmetic import intmask, signedtype, widen
-from rpython.rlib.rarithmetic import r_uint, r_ulonglong, r_longlong
+from rpython.rlib.rarithmetic import intmask, signedtype, widen, r_uint
+
def unpack_fields(space, w_fields):
fields_w = space.unpackiterable(w_fields)
@@ -269,31 +268,24 @@
return x >> 16
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
+ return (((1 << (x - 1)) - 1) << 1) + 1
BIT_MASK._annspecialcase_ = 'specialize:arg(1)'
def push_field(self, num, value):
ptr = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[num])
TP = lltype.typeOf(value)
- T = lltype.Ptr(rffi.CArray(TP))
-
# Handle bitfields
for c in unroll_letters_for_numbers:
if LL_TYPEMAP[c] is TP and self.shape.ll_bitsizes:
# Modify the current value with the bitfield changed
bitsize = self.shape.ll_bitsizes[num]
numbits = NUM_BITS(bitsize)
- lowbit = LOW_BIT(bitsize)
if numbits:
+ lowbit = LOW_BIT(bitsize)
+ bitmask = BIT_MASK(numbits, TP)
value = widen(value)
- bitmask = BIT_MASK(numbits, TP)
- #
current = widen(read_ptr(ptr, 0, TP))
- current &= ~ (bitmask << lowbit)
+ current &= ~(bitmask << lowbit)
current |= (value & bitmask) << lowbit
value = rffi.cast(TP, current)
break
@@ -302,29 +294,24 @@
def cast_pos(self, i, ll_t):
pos = rffi.ptradd(self.ll_buffer, self.shape.ll_positions[i])
- TP = lltype.Ptr(rffi.CArray(ll_t))
value = read_ptr(pos, 0, ll_t)
-
# Handle bitfields
for c in unroll_letters_for_numbers:
if LL_TYPEMAP[c] is ll_t and self.shape.ll_bitsizes:
bitsize = self.shape.ll_bitsizes[i]
numbits = NUM_BITS(bitsize)
- lowbit = LOW_BIT(bitsize)
if numbits:
+ lowbit = LOW_BIT(bitsize)
+ bitmask = BIT_MASK(numbits, ll_t)
value = widen(rffi.cast(ll_t, value))
- bitmask = BIT_MASK(numbits, ll_t)
- #
value >>= lowbit
value &= bitmask
if ll_t is lltype.Bool or signedtype(ll_t._type):
sign = (value >> (numbits - 1)) & 1
if sign:
- one = r_longlong(1) if ll_t is lltype.SignedLongLong else 1
- value = value - (one << numbits)
+ value = value - (1 << numbits)
value = rffi.cast(ll_t, value)
break
-
return value
cast_pos._annspecialcase_ = 'specialize:arg(2)'
diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -534,6 +534,15 @@
assert (y.a, y.b, y.c) == (0, -7, 0)
y.free()
+ def test_structure_single_longbit_bitfield(self):
+ import _rawffi
+ for s in [('I', 32), ('Q', 64)]:
+ Y = _rawffi.Structure([('a',) + s])
+ y = Y()
+ y.a = 10
+ assert y.a == 10
+ y.free()
+
def test_invalid_bitfields(self):
import _rawffi
raises(TypeError, _rawffi.Structure, [('A', 'c', 1)])
More information about the pypy-commit
mailing list