Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r77210:bb885a67145f
Date: 2015-05-08 15:42 +0200
http://bitbucket.org/pypy/pypy/changeset/bb885a67145f/
Log: more progress
diff --git a/pypy/module/_cffi_backend/ffi_obj.py
b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -19,6 +19,11 @@
CONSIDER_FN_AS_FNPTR = 8
+def get_ffi_error(space):
+ w_ffitype = space.gettypefor(W_FFIObject)
+ return w_ffitype.getdictvalue(space, 'error')
+
+
class W_FFIObject(W_Root):
def __init__(self, space, src_ctx=parse_c_type.NULL_CTX):
@@ -29,8 +34,7 @@
self.cached_types = [None] * parse_c_type.get_num_types(src_ctx)
else:
self.cached_types = None
- w_ffitype = space.gettypefor(W_FFIObject)
- self.w_FFIError = w_ffitype.getdictvalue(space, 'error')
+ self.w_FFIError = get_ffi_error(space)
@rgc.must_be_light_finalizer
def __del__(self):
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
@@ -264,6 +264,20 @@
def new_union_type(space, name):
return ctypestruct.W_CTypeUnion(space, name)
+def detect_custom_layout(w_ctype, sflags, cdef_value, compiler_value,
+ msg1, msg2="", msg3=""):
+ if compiler_value != cdef_value:
+ if sflags & SF_STD_FIELD_POS:
+ from pypy.module._cffi_backend.ffi_obj import get_ffi_error
+ w_FFIError = get_ffi_error(w_ctype.space)
+ raise oefmt(w_FFIError,
+ '%s: %s%s%s (cdef says %d, but C compiler says %d).'
+ ' fix it or use "...;" in the cdef for %s to '
+ 'make it flexible',
+ w_ctype.name, msg1, msg2, msg3,
+ cdef_value, compiler_value, w_ctype.name)
+ w_ctype._custom_field_pos = True
+
@unwrap_spec(w_ctype=ctypeobj.W_CType, totalsize=int, totalalignment=int,
sflags=int)
def complete_struct_or_union(space, w_ctype, w_fields, w_ignored=None,
@@ -284,7 +298,7 @@
fields_w = space.listview(w_fields)
fields_list = []
fields_dict = {}
- custom_field_pos = False
+ w_ctype._custom_field_pos = False
with_var_array = False
for i in range(len(fields_w)):
@@ -343,7 +357,9 @@
if foffset >= 0:
# a forced field position: ignore the offset just computed,
# except to know if we must set 'custom_field_pos'
- custom_field_pos |= (boffset != foffset * 8)
+ detect_custom_layout(w_ctype, sflags, boffset // 8, foffset,
+ "wrong offset for field '",
+ fname, "'")
boffset = foffset * 8
if (fname == '' and
@@ -361,7 +377,7 @@
except KeyError:
pass
# always forbid such structures from being passed by value
- custom_field_pos = True
+ w_ctype._custom_field_pos = True
else:
# a regular field
fld = ctypestruct.W_CField(ftype, boffset // 8, bs_flag, -1)
@@ -481,22 +497,30 @@
# 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.
- got = (boffsetmax + 7) // 8
+ boffsetmax = (boffsetmax + 7) // 8 # bits -> bytes
+ alignedsize = (boffsetmax + alignment - 1) & ~(alignment - 1)
+ alignedsize = alignedsize or 1
+
if totalsize < 0:
- totalsize = (got + alignment - 1) & ~(alignment - 1)
- totalsize = totalsize or 1
- elif totalsize < got:
- raise oefmt(space.w_TypeError,
- "%s cannot be of size %d: there are fields at least up to "
- "%d", w_ctype.name, totalsize, got)
+ totalsize = alignedsize
+ else:
+ detect_custom_layout(w_ctype, sflags, alignedsize, totalsize,
+ "wrong total size")
+ if totalsize < boffsetmax:
+ raise oefmt(space.w_TypeError,
+ "%s cannot be of size %d: there are fields at least up to %d",
+ w_ctype.name, totalsize, boffsetmax)
if totalalignment < 0:
totalalignment = alignment
+ else:
+ detect_custom_layout(w_ctype, sflags, alignment, totalalignment,
+ "wrong total alignment")
w_ctype.size = totalsize
w_ctype.alignment = totalalignment
w_ctype._fields_list = fields_list[:]
w_ctype._fields_dict = fields_dict
- w_ctype._custom_field_pos = custom_field_pos
+ #w_ctype._custom_field_pos = ...set above already
w_ctype._with_var_array = with_var_array
# ____________________________________________________________
diff --git a/pypy/module/_cffi_backend/realize_c_type.py
b/pypy/module/_cffi_backend/realize_c_type.py
--- a/pypy/module/_cffi_backend/realize_c_type.py
+++ b/pypy/module/_cffi_backend/realize_c_type.py
@@ -291,14 +291,19 @@
else:
raise oefmt(space.w_NotImplementedError, "field op=%d", case)
+ field_name = rffi.charp2str(fld.c_name)
+ field_size = rffi.getintfield(fld, 'c_field_size')
field_offset = rffi.getintfield(fld, 'c_field_offset')
if field_offset == -1:
xxxx
else:
- pass #detect_custom_layout()
+ newtype.detect_custom_layout(w_ctype, newtype.SF_STD_FIELD_POS,
+ w_ctf.size, field_size,
+ "wrong size for field '",
+ field_name, "'")
fields_w[i] = space.newtuple([
- space.wrap(rffi.charp2str(fld.c_name)),
+ space.wrap(field_name),
w_ctf,
space.wrap(fbitsize),
space.wrap(field_offset)])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit