[pypy-commit] cffi cffi-1.0: structs and unions, step 1

arigo noreply at buildbot.pypy.org
Thu Apr 16 15:17:35 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1729:dc74273884b6
Date: 2015-04-16 13:01 +0200
http://bitbucket.org/cffi/cffi/changeset/dc74273884b6/

Log:	structs and unions, step 1

diff --git a/new/recompiler.py b/new/recompiler.py
--- a/new/recompiler.py
+++ b/new/recompiler.py
@@ -42,6 +42,15 @@
                     self.cffi_types.append('LEN') # placeholder
         assert None not in self._typesdict.values()
         #
+        # collect all structs and unions
+        self._struct_unions = {}
+        for tp in all_decls:
+            if isinstance(tp, model.StructOrUnion):
+                self._struct_unions[tp] = None
+        for i, tp in enumerate(sorted(self._struct_unions,
+                                      key=lambda tp: tp.name)):
+            self._struct_unions[tp] = i
+        #
         # emit all bytecode sequences now
         for tp in all_decls:
             method = getattr(self, '_emit_bytecode_' + tp.__class__.__name__)
@@ -118,9 +127,10 @@
         #
         # the declaration of '_cffi_globals' and '_cffi_typenames'
         nums = {}
-        self._lsts = {"global": [], "typename": []}
+        self._lsts = {"global": [], "typename": [],
+                      "struct_union": [], "enum": []}
         self._generate("ctx")
-        for step_name in ["global", "typename"]:
+        for step_name in ["global", "typename", "struct_union", "enum"]:
             lst = self._lsts[step_name]
             nums[step_name] = len(lst)
             if nums[step_name] > 0:
@@ -132,10 +142,6 @@
                 prnt('};')
                 prnt()
         #
-        # XXX
-        nums['struct_union'] = 0
-        nums['enum'] = 0
-        #
         # the declaration of '_cffi_type_context'
         prnt('static const struct _cffi_type_context_s _cffi_type_context = {')
         prnt('  _cffi_types,')
@@ -357,6 +363,15 @@
             % (name, name, meth_kind, type_index))
 
     # ----------
+    # named structs or unions
+
+    def _generate_cpy_struct_collecttype(self, tp, name):
+        for tp1 in tp.fldtypes:
+            self._do_collect_type(tp1)
+
+    _generate_cpy_union_collecttype = _generate_cpy_struct_collecttype
+
+    # ----------
     # constants, declared with "static const ..."
 
     def _generate_cpy_const(self, is_int, name, tp=None, category='const',
@@ -468,6 +483,10 @@
             self.cffi_types[index] = CffiOp(OP_ARRAY, item_index)
             self.cffi_types[index + 1] = CffiOp(None, '%d' % (tp.length,))
 
+    def _emit_bytecode_StructType(self, tp, index):
+        struct_index = self._struct_unions[tp]
+        self.cffi_types[index] = CffiOp(OP_STRUCT_UNION, struct_index)
+
 def make_c_source(ffi, module_name, preamble, target_c_file):
     recompiler = Recompiler(ffi, module_name)
     recompiler.collect_type_table()
diff --git a/new/test_recompiler.py b/new/test_recompiler.py
--- a/new/test_recompiler.py
+++ b/new/test_recompiler.py
@@ -60,6 +60,20 @@
     check_type_table("int32_t f(void);",
                      "(FUNCTION 2)(FUNCTION_END 0)(PRIMITIVE 21)")
 
+def test_struct():
+    check_type_table("struct foo_s { int a; long b; };",
+                     "(PRIMITIVE 7)(PRIMITIVE 9)")
+
+def test_union():
+    check_type_table("union foo_u { int a; long b; };",
+                     "(PRIMITIVE 7)(PRIMITIVE 9)")
+
+def test_struct_used():
+    check_type_table("struct foo_s { int a; long b; }; int f(struct foo_s*);",
+                     "(FUNCTION 3)(POINTER 5)(FUNCTION_END 0)"
+                     "(PRIMITIVE 7)(PRIMITIVE 9)"
+                     "(STRUCT_UNION 0)")
+
 
 def test_math_sin():
     import math


More information about the pypy-commit mailing list