aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Cuni <anto.cuni@gmail.com>2011-08-01 17:24:06 +0200
committerAntonio Cuni <anto.cuni@gmail.com>2011-08-01 17:24:06 +0200
commit11dc3b4f401ad514a622ad04899d25d51b7f3072 (patch)
tree3bc265c569a754eb4e7fd5935f76915e6ed101d9
parentmerge heads (diff)
downloadpypy-11dc3b4f401ad514a622ad04899d25d51b7f3072.tar.gz
pypy-11dc3b4f401ad514a622ad04899d25d51b7f3072.tar.bz2
pypy-11dc3b4f401ad514a622ad04899d25d51b7f3072.zip
test and fix for very large structure fields which were confused with bitfields
-rw-r--r--lib_pypy/_ctypes/structure.py12
-rw-r--r--pypy/module/test_lib_pypy/ctypes_tests/test_structures.py9
2 files changed, 16 insertions, 5 deletions
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
index 26fabf7b01..1f56480f43 100644
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -34,16 +34,18 @@ def names_and_fields(self, _fields_, superclass, anonymous_fields=None):
for i, field in enumerate(all_fields):
name = field[0]
value = field[1]
+ is_bitfield = (len(field) == 3)
fields[name] = Field(name,
self._ffistruct.fieldoffset(name),
self._ffistruct.fieldsize(name),
- value, i)
+ value, i, is_bitfield)
if anonymous_fields:
resnames = []
for i, field in enumerate(all_fields):
name = field[0]
value = field[1]
+ is_bitfield = (len(field) == 3)
startpos = self._ffistruct.fieldoffset(name)
if name in anonymous_fields:
for subname in value._names:
@@ -52,7 +54,7 @@ def names_and_fields(self, _fields_, superclass, anonymous_fields=None):
subvalue = value._fieldtypes[subname].ctype
fields[subname] = Field(subname,
relpos, subvalue._sizeofinstances(),
- subvalue, i)
+ subvalue, i, is_bitfield)
else:
resnames.append(name)
names = resnames
@@ -60,8 +62,8 @@ def names_and_fields(self, _fields_, superclass, anonymous_fields=None):
self._fieldtypes = fields
class Field(object):
- def __init__(self, name, offset, size, ctype, num):
- for k in ('name', 'offset', 'size', 'ctype', 'num'):
+ def __init__(self, name, offset, size, ctype, num, is_bitfield):
+ for k in ('name', 'offset', 'size', 'ctype', 'num', 'is_bitfield'):
self.__dict__[k] = locals()[k]
def __setattr__(self, name, value):
@@ -225,7 +227,7 @@ class StructOrUnion(_CData):
field = self._fieldtypes[name]
except KeyError:
return _CData.__getattribute__(self, name)
- if field.size >> 16:
+ if field.is_bitfield:
# bitfield member, use direct access
return self._buffer.__getattr__(name)
else:
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
index d0b06795e9..a0f9a208b4 100644
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
@@ -424,6 +424,15 @@ class TestStructure(BaseCTypesTestChecker):
sys.settrace(oldtrace)
events = None
+ def test_large_fields(self):
+ # make sure that large fields are not "confused" with bitfields
+ # (because the bitfields use the higher bits of the "size" attribute)
+ Array = c_long * 8192
+ class X(Structure):
+ _fields_ = [('items', Array)]
+ obj = X()
+ assert isinstance(obj.items, Array)
+
class TestPointerMember(BaseCTypesTestChecker):
def test_1(self):