Author: Armin Rigo <[email protected]>
Branch:
Changeset: r56825:0e07105c06d5
Date: 2012-08-23 19:05 +0200
http://bitbucket.org/pypy/pypy/changeset/0e07105c06d5/
Log: Fix for anonymous nested structs.
diff --git a/pypy/module/_cffi_backend/ctypefunc.py
b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -264,6 +264,11 @@
# But on 64-bit UNIX, these two structs are passed by value
# differently: e.g. on x86-64, "b" ends up in register "rsi" in
# the first case and "rdi" in the second case.
+ #
+ # Another reason for 'custom_field_pos' would be anonymous
+ # nested structures: we lost the information about having it
+ # here, so better safe (and forbid it) than sorry (and maybe
+ # crash).
space = self.space
if ctype.custom_field_pos:
raise OperationError(space.w_TypeError,
diff --git a/pypy/module/_cffi_backend/ctypestruct.py
b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -162,6 +162,10 @@
def is_bitfield(self):
return self.bitshift >= 0
+ def make_shifted(self, offset):
+ return W_CField(self.ctype, offset + self.offset,
+ self.bitshift, self.bitsize)
+
def read(self, cdata):
cdata = rffi.ptradd(cdata, self.offset)
if self.bitshift == self.BS_REGULAR:
diff --git a/pypy/module/_cffi_backend/newtype.py
b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -182,9 +182,26 @@
if not is_union:
prev_bit_position += fbitsize
#
- fld = ctypestruct.W_CField(ftype, offset, bitshift, fbitsize)
- fields_list.append(fld)
- fields_dict[fname] = fld
+ if (len(fname) == 0 and
+ isinstance(ftype, ctypestruct.W_CTypeStructOrUnion)):
+ # a nested anonymous struct or union
+ srcfield2names = {}
+ for name, srcfld in ftype.fields_dict.items():
+ srcfield2names[srcfld] = name
+ for srcfld in ftype.fields_list:
+ fld = srcfld.make_shifted(offset)
+ fields_list.append(fld)
+ try:
+ fields_dict[srcfield2names[srcfld]] = fld
+ except KeyError:
+ pass
+ # always forbid such structures from being passed by value
+ custom_field_pos = True
+ else:
+ # a regular field
+ fld = ctypestruct.W_CField(ftype, offset, bitshift, fbitsize)
+ fields_list.append(fld)
+ fields_dict[fname] = fld
#
if maxsize < ftype.size:
maxsize = ftype.size
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit