[pypy-commit] cffi cffi-1.0: in-progress: bitfield support

arigo noreply at buildbot.pypy.org
Wed Apr 22 17:38:27 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1780:ded8861f09fd
Date: 2015-04-22 17:39 +0200
http://bitbucket.org/cffi/cffi/changeset/ded8861f09fd/

Log:	in-progress: bitfield support

diff --git a/new/realize_c_type.c b/new/realize_c_type.c
--- a/new/realize_c_type.c
+++ b/new/realize_c_type.c
@@ -466,11 +466,16 @@
         int i;
         for (i = 0; i < s->num_fields; i++, fld++) {
             _cffi_opcode_t op = fld->field_type_op;
+            int fbitsize = -1;
             PyObject *f;
             CTypeDescrObject *ctf;
 
             switch (_CFFI_GETOP(op)) {
 
+            case _CFFI_OP_BITFIELD:
+                assert(fld->field_size >= 0);
+                fbitsize = (int)fld->field_size;
+                /* fall-through */
             case _CFFI_OP_NOOP:
                 ctf = realize_c_type(builder, builder->ctx.types,
                                      _CFFI_GETARG(op));
@@ -484,8 +489,9 @@
 
             if (fld->field_offset == (size_t)-1) {
                 /* unnamed struct, with field positions and sizes entirely
-                   determined by complete_struct_or_union() and not checked */
-                assert(fld->field_size == -1);
+                   determined by complete_struct_or_union() and not checked.
+                   Or, bitfields (field_size >= 0), similarly not checked. */
+                assert(fld->field_size == (size_t)-1 || fbitsize >= 0);
             }
             else if (detect_custom_layout(ct, SF_STD_FIELD_POS,
                                      ctf->ct_size, fld->field_size,
@@ -494,7 +500,7 @@
                 return -1;
 
             f = Py_BuildValue("(sOin)", fld->name, ctf,
-                              (int)-1, (Py_ssize_t)fld->field_offset);
+                              fbitsize, (Py_ssize_t)fld->field_offset);
             if (f == NULL) {
                 Py_DECREF(fields);
                 return -1;
diff --git a/new/recompiler.py b/new/recompiler.py
--- a/new/recompiler.py
+++ b/new/recompiler.py
@@ -439,25 +439,29 @@
         flags = ('|'.join(flags)) or '0'
         if tp.fldtypes is not None:
             c_field = [approxname]
-            for fldname, fldtype in zip(tp.fldnames, tp.fldtypes):
+            for fldname, fldtype, fbitsize in tp.enumfields():
                 fldtype = self._field_type(tp, fldname, fldtype)
                 spaces = " " * len(fldname)
                 # cname is None for _add_missing_struct_unions() only
-                if cname is None or (
+                op = '_CFFI_OP_NOOP'
+                if fbitsize >= 0:
+                    op = '_CFFI_OP_BITFIELD'
+                    size = '%d /* bits */' % fbitsize
+                elif cname is None or (
                         isinstance(fldtype, model.ArrayType) and
                         fldtype.length is None):
                     size = '(size_t)-1'
                 else:
                     size = 'sizeof(((%s)0)->%s)' % (tp.get_c_name('*'), fldname)
-                if cname is None:
+                if cname is None or fbitsize >= 0:
                     offset = '(size_t)-1'
                 else:
                     offset = 'offsetof(%s, %s)' % (tp.get_c_name(''), fldname)
                 c_field.append(
                     '  { "%s", %s,\n' % (fldname, offset) +
                     '     %s   %s,\n' % (spaces, size) +
-                    '     %s   _CFFI_OP(_CFFI_OP_NOOP, %s) },' % (
-                            spaces, self._typesdict[fldtype]))
+                    '     %s   _CFFI_OP(%s, %s) },' % (
+                            spaces, op, self._typesdict[fldtype]))
             self._lsts["field"].append('\n'.join(c_field))
             #
             if cname is None:  # unknown name, for _add_missing_struct_unions


More information about the pypy-commit mailing list