[pypy-commit] pypy default: update to cffi/46c06e1fd666
arigo
pypy.commits at gmail.com
Sun Sep 29 03:57:27 EDT 2019
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r97671:d648cf5b8009
Date: 2019-09-29 09:56 +0200
http://bitbucket.org/pypy/pypy/changeset/d648cf5b8009/
Log: update to cffi/46c06e1fd666
diff --git a/extra_tests/cffi_tests/cffi1/test_re_python.py b/extra_tests/cffi_tests/cffi1/test_re_python.py
--- a/extra_tests/cffi_tests/cffi1/test_re_python.py
+++ b/extra_tests/cffi_tests/cffi1/test_re_python.py
@@ -66,7 +66,7 @@
int add43(int, ...);
int globalvar42;
const int globalconst42;
- const char *const globalconsthello = "hello";
+ const char *const globalconsthello;
int no_such_function(int);
int no_such_globalvar;
struct foo_s;
diff --git a/lib_pypy/cffi/backend_ctypes.py b/lib_pypy/cffi/backend_ctypes.py
--- a/lib_pypy/cffi/backend_ctypes.py
+++ b/lib_pypy/cffi/backend_ctypes.py
@@ -403,7 +403,7 @@
source = _cast_source_to_int(source)
return cls(bool(source))
def __int__(self):
- return self._value
+ return int(self._value)
if kind == 'char':
@classmethod
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
@@ -313,6 +313,10 @@
cdef_value, compiler_value, w_ctype.name)
w_ctype._custom_field_pos = True
+def roundup_bytes(bytes, bit):
+ assert bit == (bit & 7)
+ return bytes + (bit > 0)
+
@unwrap_spec(w_ctype=ctypeobj.W_CType, totalsize=int, totalalignment=int,
sflags=int, pack=int)
def complete_struct_or_union(space, w_ctype, w_fields, w_ignored=None,
@@ -334,8 +338,9 @@
is_union = isinstance(w_ctype, ctypestruct.W_CTypeUnion)
alignment = 1
- boffset = 0 # this number is in *bits*, not bytes!
- boffsetmax = 0 # the maximum value of boffset, in bits too
+ byteoffset = 0 # the real value is 'byteoffset+bitoffset*8', which
+ bitoffset = 0 # counts the offset in bits
+ byteoffsetmax = 0 # the maximum value of byteoffset-rounded-up-to-byte
prev_bitfield_size = 0
prev_bitfield_free = 0
fields_w = space.listview(w_fields)
@@ -380,7 +385,7 @@
with_var_array = True
#
if is_union:
- boffset = 0 # reset each field at offset 0
+ byteoffset = bitoffset = 0 # reset each field at offset 0
#
# update the total alignment requirement, but skip it if the
# field is an anonymous bitfield or if SF_PACKED
@@ -410,19 +415,24 @@
else:
bs_flag = ctypestruct.W_CField.BS_REGULAR
- # align this field to its own 'falign' by inserting padding
- boffsetorg = (boffset + falignorg*8-1) & ~(falignorg*8-1)
- boffset = (boffset + falign*8-1) & ~(falign*8-1)
- if boffsetorg != boffset:
+ # align this field to its own 'falign' by inserting padding.
+ # first, pad to the next byte,
+ # then pad to 'falign' or 'falignorg' bytes
+ byteoffset = roundup_bytes(byteoffset, bitoffset)
+ bitoffset = 0
+ byteoffsetorg = (byteoffset + falignorg-1) & ~(falignorg-1)
+ byteoffset = (byteoffset + falign-1) & ~(falign-1)
+
+ if byteoffsetorg != byteoffset:
with_packed_change = True
if foffset >= 0:
# a forced field position: ignore the offset just computed,
# except to know if we must set 'custom_field_pos'
- detect_custom_layout(w_ctype, sflags, boffset // 8, foffset,
+ detect_custom_layout(w_ctype, sflags, byteoffset, foffset,
"wrong offset for field '",
fname, "'")
- boffset = foffset * 8
+ byteoffset = foffset
if (fname == '' and
isinstance(ftype, ctypestruct.W_CTypeStructOrUnion)):
@@ -432,7 +442,7 @@
for name, srcfld in ftype._fields_dict.items():
srcfield2names[srcfld] = name
for srcfld in ftype._fields_list:
- fld = srcfld.make_shifted(boffset // 8, fflags)
+ fld = srcfld.make_shifted(byteoffset, fflags)
fields_list.append(fld)
try:
fields_dict[srcfield2names[srcfld]] = fld
@@ -442,13 +452,13 @@
w_ctype._custom_field_pos = True
else:
# a regular field
- fld = ctypestruct.W_CField(ftype, boffset // 8, bs_flag, -1,
+ fld = ctypestruct.W_CField(ftype, byteoffset, bs_flag, -1,
fflags)
fields_list.append(fld)
fields_dict[fname] = fld
if ftype.size >= 0:
- boffset += ftype.size * 8
+ byteoffset += ftype.size
prev_bitfield_size = 0
else:
@@ -474,7 +484,7 @@
# compute the starting position of the theoretical field
# that covers a complete 'ftype', inside of which we will
# locate the real bitfield
- field_offset_bytes = boffset // 8
+ field_offset_bytes = byteoffset
field_offset_bytes &= ~(falign - 1)
if fbitsize == 0:
@@ -484,11 +494,13 @@
w_ctype.name, fname)
if (sflags & SF_MSVC_BITFIELDS) == 0:
# GCC's notion of "ftype :0;"
- # pad boffset to a value aligned for "ftype"
- if boffset > field_offset_bytes * 8:
+ # pad byteoffset to a value aligned for "ftype"
+ if (roundup_bytes(byteoffset, bitoffset) >
+ field_offset_bytes):
field_offset_bytes += falign
- assert boffset < field_offset_bytes * 8
- boffset = field_offset_bytes * 8
+ assert byteoffset < field_offset_bytes
+ byteoffset = field_offset_bytes
+ bitoffset = 0
else:
# MSVC's notion of "ftype :0;
# Mostly ignored. It seems they only serve as
@@ -503,7 +515,8 @@
# Can the field start at the offset given by 'boffset'? It
# can if it would entirely fit into an aligned ftype field.
- bits_already_occupied = boffset - (field_offset_bytes * 8)
+ bits_already_occupied = (
+ (byteoffset-field_offset_bytes) * 8 + bitoffset)
if bits_already_occupied + fbitsize > 8 * ftype.size:
# it would not fit, we need to start at the next
@@ -516,13 +529,16 @@
"the previous field",
w_ctype.name, fname)
field_offset_bytes += falign
- assert boffset < field_offset_bytes * 8
- boffset = field_offset_bytes * 8
+ assert byteoffset < field_offset_bytes
+ byteoffset = field_offset_bytes
+ bitoffset = 0
bitshift = 0
else:
bitshift = bits_already_occupied
assert bitshift >= 0
- boffset += fbitsize
+ bitoffset += fbitsize
+ byteoffset += (bitoffset >> 3)
+ bitoffset &= 7
else:
# MSVC's algorithm
@@ -537,14 +553,17 @@
bitshift = 8 * prev_bitfield_size - prev_bitfield_free
else:
# no: start a new full field
- boffset = (boffset + falign*8-1) & ~(falign*8-1)
- boffset += ftype.size * 8
+ byteoffset = roundup_bytes(byteoffset, bitoffset)
+ bitoffset = 0
+ # align
+ byteoffset = (byteoffset + falign-1) & ~(falign-1)
+ byteoffset += ftype.size
bitshift = 0
prev_bitfield_size = ftype.size
prev_bitfield_free = 8 * prev_bitfield_size
#
prev_bitfield_free -= fbitsize
- field_offset_bytes = boffset / 8 - ftype.size
+ field_offset_bytes = byteoffset - ftype.size
if sflags & SF_GCC_BIG_ENDIAN:
bitshift = 8 * ftype.size - fbitsize- bitshift
@@ -555,14 +574,13 @@
fields_list.append(fld)
fields_dict[fname] = fld
- if boffset > boffsetmax:
- boffsetmax = boffset
+ if roundup_bytes(byteoffset, bitoffset) > byteoffsetmax:
+ byteoffsetmax = roundup_bytes(byteoffset, bitoffset)
# Like C, if the size of this structure would be zero, we compute it
# as 1 instead. But for ctypes support, we allow the manually-
# specified totalsize to be zero in this case.
- boffsetmax = (boffsetmax + 7) // 8 # bits -> bytes
- alignedsize = (boffsetmax + alignment - 1) & ~(alignment - 1)
+ alignedsize = (byteoffsetmax + alignment - 1) & ~(alignment - 1)
alignedsize = alignedsize or 1
if totalsize < 0:
@@ -570,10 +588,10 @@
else:
detect_custom_layout(w_ctype, sflags, alignedsize, totalsize,
"wrong total size")
- if totalsize < boffsetmax:
+ if totalsize < byteoffsetmax:
raise oefmt(space.w_TypeError,
"%s cannot be of size %d: there are fields at least up to %d",
- w_ctype.name, totalsize, boffsetmax)
+ w_ctype.name, totalsize, byteoffsetmax)
if totalalignment < 0:
totalalignment = alignment
else:
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -4432,3 +4432,11 @@
f = cast(BFunc, 0)
with pytest.raises(RuntimeError):
f(40, 2)
+
+def test_huge_structure():
+ BChar = new_primitive_type("char")
+ BArray = new_array_type(new_pointer_type(BChar), sys.maxsize)
+ assert sizeof(BArray) == sys.maxsize
+ BStruct = new_struct_type("struct foo")
+ complete_struct_or_union(BStruct, [('a1', BArray, -1)])
+ assert sizeof(BStruct) == sys.maxsize
diff --git a/pypy/tool/import_cffi.py b/pypy/tool/import_cffi.py
--- a/pypy/tool/import_cffi.py
+++ b/pypy/tool/import_cffi.py
@@ -20,6 +20,10 @@
else:
raise AssertionError(ext)
+def fixeol(s):
+ s = s.replace('\r\n', '\n')
+ return s
+
def main(cffi_dir):
cffi_dir = py.path.local(cffi_dir)
rootdir = py.path.local(__file__).join('..', '..', '..')
@@ -29,13 +33,13 @@
test_dest.ensure(dir=1)
for p in (list(cffi_dir.join('cffi').visit(fil='*.py')) +
list(cffi_dir.join('cffi').visit(fil='*.h'))):
- cffi_dest.join('..', p.relto(cffi_dir)).write(p.read())
+ cffi_dest.join('..', p.relto(cffi_dir)).write_binary(fixeol(p.read()))
for p in (list(cffi_dir.join('testing').visit(fil='*.py')) +
list(cffi_dir.join('testing').visit(fil='*.h')) +
list(cffi_dir.join('testing').visit(fil='*.c'))):
path = test_dest.join(p.relto(cffi_dir.join('testing')))
path.join('..').ensure(dir=1)
- path.write(''.join(mangle(p.readlines(), p.ext)))
+ path.write_binary(fixeol(''.join(mangle(p.readlines(), p.ext))))
if __name__ == '__main__':
if len(sys.argv) != 2:
More information about the pypy-commit
mailing list