diff options
author | Antonio Cuni <anto.cuni@gmail.com> | 2011-08-01 17:24:06 +0200 |
---|---|---|
committer | Antonio Cuni <anto.cuni@gmail.com> | 2011-08-01 17:24:06 +0200 |
commit | 11dc3b4f401ad514a622ad04899d25d51b7f3072 (patch) | |
tree | 3bc265c569a754eb4e7fd5935f76915e6ed101d9 | |
parent | merge heads (diff) | |
download | pypy-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.py | 12 | ||||
-rw-r--r-- | pypy/module/test_lib_pypy/ctypes_tests/test_structures.py | 9 |
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): |