[pypy-commit] pypy cpyext-gc-support: Support varsized arrays at the end of structs
arigo
noreply at buildbot.pypy.org
Tue Oct 20 12:31:15 EDT 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support
Changeset: r80356:5dbf9e6ec173
Date: 2015-10-20 17:10 +0200
http://bitbucket.org/pypy/pypy/changeset/5dbf9e6ec173/
Log: Support varsized arrays at the end of structs
diff --git a/rpython/rtyper/tool/rffi_platform.py b/rpython/rtyper/tool/rffi_platform.py
--- a/rpython/rtyper/tool/rffi_platform.py
+++ b/rpython/rtyper/tool/rffi_platform.py
@@ -313,7 +313,9 @@
offset = info['fldofs ' + fieldname]
size = info['fldsize ' + fieldname]
sign = info.get('fldunsigned ' + fieldname, False)
- if (size, sign) != rffi.size_and_sign(fieldtype):
+ if is_array_nolength(fieldtype):
+ pass # ignore size and sign
+ elif (size, sign) != rffi.size_and_sign(fieldtype):
fieldtype = fixup_ctype(fieldtype, fieldname, (size, sign))
layout_addfield(layout, offset, fieldtype, fieldname)
@@ -682,8 +684,14 @@
def __repr__(self):
return '<field %s: %s>' % (self.name, self.ctype)
+def is_array_nolength(TYPE):
+ return isinstance(TYPE, lltype.Array) and TYPE._hints.get('nolength', False)
+
def layout_addfield(layout, offset, ctype, prefix):
- size = _sizeof(ctype)
+ if is_array_nolength(ctype):
+ size = len(layout) - offset # all the rest of the struct
+ else:
+ size = _sizeof(ctype)
name = prefix
i = 0
while name in layout:
diff --git a/rpython/rtyper/tool/test/test_rffi_platform.py b/rpython/rtyper/tool/test/test_rffi_platform.py
--- a/rpython/rtyper/tool/test/test_rffi_platform.py
+++ b/rpython/rtyper/tool/test/test_rffi_platform.py
@@ -270,6 +270,19 @@
[("d_name", lltype.FixedSizeArray(rffi.CHAR, 1))])
assert dirent.c_d_name.length == 32
+def test_array_varsized_struct():
+ dirent = rffi_platform.getstruct("struct dirent",
+ """
+ struct dirent /* for this example only, not the exact dirent */
+ {
+ int d_off;
+ char d_name[1];
+ };
+ """,
+ [("d_name", rffi.CArray(rffi.CHAR))])
+ assert rffi.offsetof(dirent, 'c_d_name') == 4
+ assert dirent.c_d_name == rffi.CArray(rffi.CHAR)
+
def test_has_0001():
assert rffi_platform.has("x", "int x = 3;")
assert not rffi_platform.has("x", "")
More information about the pypy-commit
mailing list