[pypy-commit] pypy cffi-1.0: opaque structs

arigo noreply at buildbot.pypy.org
Fri May 8 14:29:26 CEST 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r77207:7dc03f1911ef
Date: 2015-05-08 14:29 +0200
http://bitbucket.org/pypy/pypy/changeset/7dc03f1911ef/

Log:	opaque structs

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
@@ -148,11 +148,58 @@
     return x
 
 
+def _realize_name(prefix, charp_src_name):
+    # "xyz" => "struct xyz"
+    #"$xyz" => "xyz"
+    if charp_src_name[0] == '$' and charp_src_name[1] != '$':
+        return rffi.charp2str(rffi.ptradd(charp_src_name, 1))
+    else:
+        return prefix + rffi.charp2str(charp_src_name)
+
+
+def _realize_c_struct_or_union(ffi, sindex):
+    s = ffi.ctxobj.ctx.c_struct_unions[sindex]
+    type_index = rffi.getintfield(s, 'c_type_index')
+    if ffi.cached_types[type_index] is not None:
+        return ffi.cached_types[type_index] #found already in the "primary" slot
+
+    w_ctype = None
+    s_flags = rffi.getintfield(s, 'c_flags')
+    if (s_flags & cffi_opcode.F_EXTERNAL) == 0:
+        space = ffi.space
+        if (s_flags & cffi_opcode.F_UNION) != 0:
+            name = _realize_name("union ", s.c_name)
+            x = newtype.new_union_type(space, name)
+        else:
+            name = _realize_name("struct ", s.c_name)
+            x = newtype.new_struct_type(space, name)
+        if rffi.getintfield(s, 'c_first_field_index') >= 0:
+            w_ctype = x
+            xxxx
+    else:
+        yyyy
+
+    # Update the "primary" OP_STRUCT_UNION slot
+    ffi.cached_types[type_index] = x
+
+    if w_ctype is not None and rffi.getintfield(s, 'c_size') == -2:
+        # oops, this struct is unnamed and we couldn't generate
+        # a C expression to get its size.  We have to rely on
+        # complete_struct_or_union() to compute it now.
+        try:
+            xxxx / do_realize_lazy_struct(w_ctype)
+        except:
+            ffi.cached_types[type_index] = None
+            raise
+    return x
+
+
 def realize_c_type_or_func(ffi, opcodes, index):
     op = opcodes[index]
 
-    from_ffi = False
-    #...
+    from_ffi = (opcodes == ffi.ctxobj.ctx.c_types)
+    if from_ffi and ffi.cached_types[index] is not None:
+        return ffi.cached_types[index]
 
     case = getop(op)
 
@@ -175,6 +222,9 @@
     elif case == cffi_opcode.OP_OPEN_ARRAY:
         x = get_array_type(ffi, opcodes, getarg(op), -1)
 
+    elif case == cffi_opcode.OP_STRUCT_UNION:
+        x = _realize_c_struct_or_union(ffi, getarg(op))
+
     elif case == cffi_opcode.OP_FUNCTION:
         y = realize_c_type(ffi, opcodes, getarg(op))
         base_index = index + 1
@@ -203,6 +253,7 @@
         raise oefmt(ffi.space.w_NotImplementedError, "op=%d", case)
 
     if from_ffi:
-        yyyy # ...
+        assert ffi.cached_types[index] is None or ffi.cached_types[index] is x
+        ffi.cached_types[index] = x
 
     return x


More information about the pypy-commit mailing list